def update
@product_category = @business_category.product_categories.find(params[:id])
product_category_was = @business_category.product_categories.find(params[:id])
respond_to do |format|
if @product_category.update_attributes(params[:product_category])
share_associations(@product_category, product_category_was) if in_params('_map开发者_如何学Pythons_attributes', 'product_category')
format.js
format.html { redirect_to(admin_product_categories_path, :notice => 'Product category was successfully updated.') }
format.xml { head :ok }
else
format.js
format.html { render :action => "edit" }
format.xml { render :xml => @product_category.errors, :status => :unprocessable_entity }
end
end
end
The function share_associations has the parameters @product_category and product_category_was. The problem is, when i call product_category_was.send('images') for example (which i have to call using send since the call is dynamic) it obviously pulls the newest associated images and not the images that were associated. Is there anyway i can get the object to get the images that were associated at the point in time it was made?
I think you need a deep copy of your object, because normal association (=
) will only create a reference:
product_category_was = Marshal::load(Marshal::dump(@product_category))
This might not work for all kinds of objects, but for normal Rails objects this should work.
I have no idea what arnep is talking about, nor what problem you're getting. What you're doing works for me on two different finds through an association, and so it should.
irb(main):016:0> s = School.first
=> #<School id: 2, name: "Bar", created_at: "2011-04-09 17:48:57", updated_at: "2011-05-13 09:13:38", confirmed: nil, zipcode: nil>
irb(main):017:0> g1 = s.grades.find 4
=> #<Grade id: 4, name: "4th", type: nil, school_id: 2, created_at: "2011-04-19 03:17:49", updated_at: "2011-05-13 09:15:17">
irb(main):018:0> g2 = s.grades.find 4
=> #<Grade id: 4, name: "4th", type: nil, school_id: 2, created_at: "2011-04-19 03:17:49", updated_at: "2011-05-13 09:15:17">
irb(main):019:0> g1.update_attributes :name => '5th'
=> true
irb(main):020:0> g2
=> #<Grade id: 4, name: "4th", type: nil, school_id: 2, created_at: "2011-04-19 03:17:49", updated_at: "2011-05-13 09:15:17">
irb(main):021:0> g1
=> #<Grade id: 4, name: "5th", type: nil, school_id: 2, created_at: "2011-04-19 03:17:49", updated_at: "2011-05-13 09:16:02">
irb(main):022:0>
In fact, usually people are asking the inverse question - how to get an already instantiated object to reload from the DB. The problem is probably in your share_associations
method, or something else you're not showing yet.
I found a way to do something that works for now. It's not the greatest way, but it works for now. I basically created an empty array and pushed the product_categories array into it. This made it so the value was no longer a call so the value does not change. Hopefully this will help someone else eventually.
def update
@product_category = @business_category.product_categories.find(params[:id])
if in_params('_maps_attributes', 'product_category')
media_was = Array.new
media_was = media_was | @business_category.product_categories.find(params[:id]).send(map_type('product_category').pluralize)
end
respond_to do |format|
if @product_category.update_attributes(params[:product_category])
share_associations(@product_category, media_was) if in_params('_maps_attributes', 'product_category')
format.js
format.html { redirect_to(admin_product_categories_path, :notice => 'Product category was successfully updated.') }
format.xml { head :ok }
else
format.js
format.html { render :action => "edit" }
format.xml { render :xml => @product_category.errors, :status => :unprocessable_entity }
end
end
end
精彩评论