Peter Marklund

Peter Marklund's Home

Wed March 28, 2007
Programming

Rails Gotcha: No ordering of ActiveRecord after_save callbacks

I am setting up tagging and searching for a demo application and I am combining the plugins acts_as_taggable_on_steroids and acts_as_ferret. I was using the following setup for my users:

  acts_as_ferret :fields => [:login, :email, :bio, :tags_string]

  def tags_string
    tags.map(&:name).join(" ")
  end

However, that didn't work. When making a change to my tags I had to save the user twice for the search index to be updated. Why? Because the acts_as_taggable_on_steroid after_save callback (save_tags) runs after the acts_as_ferret after_save callback (ferret_update). Maybe the callbacks are invoked alphabetically, I don't know. Anyway, there is no explicit ordering and no after_after_save callback...

The workaround in this case was easy because of the virtual attribute tag_list that gets set before the save:

    def tags_string
      Tag.parse(tag_list).join(" ")
    end

Now we are always using the latest tag list when we update the Ferret index. Problem solved.

Comments

Duncan Beevers said over 6 years ago:

ActiveRecord callbacks can be queued using the Inheritable Callback Queue by using class methods such as after_save, as opposed to defining an explicit after_save on your model.

http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html

--------------------------------------------------------------------------------