Updating a new record with an after_save callback

We have a Photo model in which we want to store a list of actors featured in that photo, to make it easier for Solr to search photos. When a new photo is uploaded users can associate one or more actors with the photo. This arrives from our form submission as actor id’s.

So we’d like to have an after_save callback that looks up the actor names and adds them to our special index field. Problem is, if we have this

class Photo < ActiveRecord::Base
  after_save :set_index_representations

  private

  def set_index_representations
    update_attribute :index_repr_of_actors, actors.all.collect{|p| p.full_name }.join(" ")
  end

then our after_save gets called again after we’ve updated our new field. Oops! Endless loop.

We need a way of updating the record without calling after_save again. The solution is update_all.

def set_index_representations
  Photo.update_all( "index_repr_of_actors = '#{ actors.all.collect{ |p| p.full_name }.join(" ") }'", "id = #{id}")
end

Just be sure to specify the condition, otherwise you’ll end up updating all records!