ruby-on-railsruby-on-rails-3before-filterupdate-attributesbefore-save

How to "update_attributes" without executing "before_save"?


I have a before_save in my Message model defined like this:

   class Message < ActiveRecord::Base
     before_save lambda { foo(publisher); bar }
   end

When I do:

   my_message.update_attributes(:created_at => ...)

foo and bar are executed.

Sometimes, I would like to update message's fields without executing foo and bar.

How could I update, for example, the created_at field (in the database) without executing foo and bar ?


Solution

  • In rails 3.1 you will use update_column.

    Otherwise:

    In general way, the most elegant way to bypass callbacks is the following:

    class Message < ActiveRecord::Base
      cattr_accessor :skip_callbacks
      before_save lambda { foo(publisher); bar }, :unless => :skip_callbacks # let's say you do not want this callback to be triggered when you perform batch operations
    end
    

    Then, you can do:

    Message.skip_callbacks = true # for multiple records
    my_message.update_attributes(:created_at => ...)
    Message.skip_callbacks = false # reset
    

    Or, just for one record:

    my_message.update_attributes(:created_at => ..., :skip_callbacks => true)
    

    If you need it specifically for a Time attribute, then touch will do the trick as mentioned by @lucapette .