This project is archived and is in readonly mode.

#2207 ✓invalid
Emmanuel Nicolau

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

Reported by Emmanuel Nicolau | March 11th, 2009 @ 02:19 AM | in 2.x


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

Comments and changes to this ticket

  • Emmanuel Nicolau

    Emmanuel Nicolau March 11th, 2009 @ 02:23 AM

    • 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”
  • Eloy Duran

    Eloy Duran March 11th, 2009 @ 02:53 PM

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

    Eloy Duran March 11th, 2009 @ 03:05 PM

    • Milestone set to 2.x
  • Emmanuel Nicolau

    Emmanuel Nicolau March 11th, 2009 @ 10:32 PM

    update_attributes! doesn't call after_save either.

  • rdavila

    rdavila April 21st, 2010 @ 09:48 PM

    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" }]
    
  • Chris Flipse

    Chris Flipse April 24th, 2010 @ 07:56 PM

    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.

  • Jeremy Kemper

    Jeremy Kemper April 24th, 2010 @ 09:57 PM

    • State changed from “open” to “invalid”

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2 style="font-size: 14px">Tickets have moved to Github</h2>

The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>

Pages