Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

When using accepts_nested_attributes_for, update_attributes! on association doesn't call after_update callback

#2207

class Person < ActiveRecord::Base
  has_many :children
  accepts_nested_attributes_for :children
end

class Child < ActiveRecord::Base
  belongs_to :person
  after_update :do_something
  
  def do_something
    puts 'on after_update'
  end
end

p = Person.create!(:name => "Smith", :children_attributes => {"new_1" => {:name => "John"}})
# => #<Person id: 5 ...>

p.update_attributes :name => "Smith29", :children_attributes => {p.children.first.id => {:name => "John"}} 
# "on after_update"

p.update_attributes! :name => "Smith29", :children_attributes => {p.children.first.id => {:name => "John"}} 
# prints nothing

Reported by Emmanuel Nicolau · March 11th, 2009 @ 02:19 AM

State: invalid
Milestone: 2.x
Assigned to: Eloy Duran Eloy Duran
Importance: none

Activity

  1. Emmanuel Nicolau
    Emmanuel Nicolau
    • Title changed from When using accepts_nested_attributes_for update_attributes! on association doesn't call after_update callback to When using accepts_nested_attributes_for, update_attributes! on association doesn't call after_update callback

    March 11th, 2009 @ 02:23 AM

  2. Eloy Duran
    Eloy Duran
    • Assigned user set to Eloy Duran
    • State changed from new to open
    • Milestone cleared.

    March 11th, 2009 @ 02:53 PM

  3. Eloy Duran
  4. Emmanuel Nicolau
    Emmanuel Nicolau

    update_attributes! doesn't call after_save either.

    March 11th, 2009 @ 10:32 PM

  5. rdavila
    rdavila

    This works fine for me in Rails 2.3.5 and Ruby 1.8.7, and the correct syntax is:

    p.update_attributes! :name => "Smith29", :children_attributes => [{ :id => p.children.first.id, :name => "John" }]
    

    April 21st, 2010 @ 09:48 PM

  6. Chris Flipse
    Chris Flipse

    This actually looks like it's not a bug -- it's the dirty attributes behaving correctly

    p = Person.create!(:name => "Smith", :children_attributes => {"new_1" => {:name => "John"}})
    # after save
    # => #<Person id: 3 ...>
    
    p.update_attributes! :name => "Smith29", :children_attributes => [{ :id => p.children.first.id, :name => "John" }]
    # => true 
    
    p.update_attributes! :name => "Smith30", :children_attributes => [{ :id => p.children.first.id, :name => "Joe" }]
    after update
    after save
    # => true
    

    First update doesn't actually change the child's attributes, so it's never marked as dirty, so it's never acutally saved.

    Second update changes the child's attributes, and the callbacks work fine.

    April 24th, 2010 @ 07:56 PM

  7. Jeremy Kemper
    Jeremy Kemper
    • State changed from open to invalid

    April 24th, 2010 @ 09:57 PM