Skip to content


Subversion checkout URL

You can clone with
Download ZIP


Callback bug where `after_update` runs inappropriately on associated model #13360

nfm opened this Issue · 2 comments

3 participants


I think I've hit a pretty obscure callback related issue.

After creating a record that references an associated model in its after_create callback, the associated model's after_update callback can be run, even if that model was not updated.

gem 'activerecord', '4.0.2'
require 'active_record'

# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')

ActiveRecord::Schema.define do
  create_table :users do |t|

  create_table :posts do |t|
    t.integer :user_id

  create_table :comments do |t|
    t.integer :post_id

class User < ActiveRecord::Base
  has_many :posts

  after_update :this_should_not_run

  def this_should_not_run
    puts "But it does, even though the user wasn't updated"

class Post < ActiveRecord::Base
  belongs_to :user
  has_many :comments

class Comment < ActiveRecord::Base
  after_create :reference_user

  has_one :user, through: :post
  belongs_to :post

  def reference_user
    puts "If I load my user its after_update callback runs! #{}"

user = User.create
post = user.posts.create
comment =

Running the above script will output the strings from both callbacks. The user isn't being touched or modified, just referenced from the comment's callback. If you remove the call from the comment's callback, the user's callback doesn't run.

The has_one through association is required to reproduce the bug. Moving the after_update callback to the post model, and referencing the post from the comment's after_create doesn't trigger the bug.

My current workaround is to define the after_create callback after the comment model's associations. This somehow avoids the after_update callback being triggered inappropriately.

I initially hit this bug on 3.2.16, but it looks like it's still present on 4.0.2.

Not sure where to dig in and get started on this, it's pretty obscure. Does anyone have any thoughts?

@nfm nfm added the stale label

This issue has been automatically marked as stale because it has not been commented on for at least
three months.

The resources of the Rails team are limited, and so we are asking for your help.

If you can still reproduce this error on the 4-1-stable, 4-0-stable branches or on master,
please reply with all of the information you have about it in order to keep the issue open.

Thank you for all your contributions.

dv commented

Issue remains.

This is an issue in AutosaveAssociations. From autosave docs:

  # Note that <tt>autosave: false</tt> is not same as not declaring <tt>:autosave</tt>.
  # When the <tt>:autosave</tt> option is not present then new association records are
  # saved but the updated association records are not saved.


  # Association with autosave option defines several callbacks on your
  # model (before_save, after_create, after_update). Please note that
  # callbacks are executed in the order they were defined in
  # model. 

Autosave is only applicable when the parent object is loaded. Your reference_user callback makes sure of this, but this can more easily be shown by doing this instead of that callback:

# ...
post = user.posts.create
comment =

The reason the callback needs to be defined before the association for the bug to present itself is because callbacks are called in the order you defined them. If the reference_user callback is run after the Autosave check, the User object is obviously not there for the Autosave check.

The problem exists because even though the User object is not changed, it is also being saved. Looking at the code it appears this should only happen if the User object is also changed.

@rafaelfranca rafaelfranca added attached PR and removed stale labels
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.