Search code examples
ruby-on-railsobservers

nested attributes update triggers wrong callback in observer


Two classes in the app/model:

class Job
  accepts_nested_attributes_for :address
end

class Address
end

Then in jobs_controller, update method, I do @job.update(job_params), address params included in the job_params from the form submission.

The address can be updated correctly, however the address observer does not behave properly. Instead after_updated be called, it actually triggers after_create when address gets updated.

address_observer.rb

# cannot be triggered when address gets updated
def after_update(address)
end

# can be triggered when address gets updated
def after_create(address)
end

Cannot figure it out why, anyone could give some help on this? Thanks a lot in advance.


Solution

  • In your case, you need to make sure your parameters are passed in with a key address_attributes, and the correct id. If you do not include the id, a record will be created. This is why after_create is firing instead of after_update.

    Here's an example (assuming a has_one relation:)

    { job: { address_attributes: { id: 1, foo: 'bar' } } }
    

    Here is the relevant documentation: ActiveRecord::NestedAttributes::ClassMethods

    You can now set or update attributes on the associated posts through an attribute hash for a member: include the key :posts_attributes with an array of hashes of post attributes as a value. For each hash that does not have an id key a new record will be instantiated [...]