Reputation:
I have a nested models set :
class Event < ActiveRecord::Base
belongs_to :place
:place
attr_accessible :place_attributes, :reject_if => :all_blank, :allow_destroy => false
class Place < ActiveRecord::Base
has_many :events
validates :label, :presence => true,
:uniqueness => {:case_sensitive => true, :on => :create }
validates :description, :presence => {:on => :create},
:uniqueness => {:case_sensitive => true , :on => :create}
In a test scenario, w the nested form, the user can update only the Place#label attributes, keeping all the other information..
test "should_update_event_place_data" do
put :update, :locale => I18n.locale, :id => @event[:id],
:event => { :place_attributes => { label: "a very beautiful place" } }
which leads to a request to EventsController#update, receiving the parameters :
params
{"event"=>{"place_attributes"=>{"label"=>"a very beautiful place"}}, "locale"=>"en",
"id"=>"145", "controller"=>"backoffice/events", "action"=>"update"}
(rdb:1) @event.update_attributes(params[:event])
false
@messages={:"place.description"=>["cannot be blank"]
But the validation is on create , not update .... no validation error should be detected .. what could be wrong ?
thanks for help
I did more testing
debugger , right after the test setup ( before sending the put request)
@event_0
#<Event id: 161, account_id: 3, place_id: 249, slug: "my-new-event-on-2013-01-01-at- edinburgh-united-king...", title: "My New Event"
@event_0.place
#<Place id: 249, label: "new fake place",..
test request:
put :update, :locale => I18n.locale, :id => @event_0[:id], :event => { :place_attributes => { label: "a very beautiful place"} }
params in request are OK, @request/method = PUT
In EventsController#update
@event.update_attributes(params[:event])
.... I inserted a debug in the Place model...
(before_validation :i_am_on_create, :on => :create)
def i_am_on_create
debugger
p "CREATING"
end
and it's creating !! don't understand why it's not updating the parent nested model
Upvotes: 0
Views: 365
Reputation: 5688
update_attributes does not propagate the updates to associations. If you watch the source code (http://apidock.com/rails/ActiveRecord/Base/update_attributes) you'll see that the #save is called in the end. And this is the default behaviour:
# existing resource 'mazeratti car'
car.name = "Wheelz"
car.brand.label = "Ferrari"
car.save
car.reload
car.name #=> "Wheelz"
car.brand.label #=> "Mazeratti"
if you want associations to be updated all the time the object is updated, look into using "autosave" (http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/belongs_to : Options)
Upvotes: 1
Reputation:
SOLVED
in order to update the nested model, I need to add the model instance id :
put :update, :locale => I18n.locale, :id => @event_0[:id], :event => { :place_attributes => { id: @event_0.place[:id], label: "a very beautiful place"} }
so in :place_attributes , I added the existing @event_0.place[:id] , and it's now updating
I found it in Anson answer on Feb 17 at 17:04 bottom page at accepts_nested_attributes_for with find_or_create?
Upvotes: 0
Reputation: 1325
If you're only wanting to test that the label attribute is updated, why not try doing update_attribute on that field only rather than the whole 'event'? Something like:
@event.place_attributes.update_attribute(
:label => params[:event][:place_attributes][:label]
)
Not tested - but you get the idea...
Upvotes: 0