Reputation: 1005
I need to override the rails (active record) update_all
method so that it always updates the updated_at
field as well. How should I go about achieving this?
Upvotes: 2
Views: 1430
Reputation: 24340
Put the following code in a file /config/initializers/update_all_with_touch.rb
class ActiveRecord::Relation
def update_all_with_touch(updates, conditions = nil, options = {})
now = Time.now
# Inject the 'updated_at' column into the updates
case updates
when Hash; updates.merge!(updated_at: now)
when String; updates += ", updated_at = '#{now.to_s(:db)}'"
when Array; updates[0] += ', updated_at = ?'; updates << now
end
update_all_without_touch(updates, conditions, options)
end
alias_method_chain :update_all, :touch
end
It automatically adds the parameter :updated_at => Time.now
whenever you use update_all
.
Explanation:
This snippet use alias_method_chain
to override the default of update_all
:
alias_method_chain :update_all, :touch
The method update_all
is replaced by the method update_all_with_touch
I've defined, and the original update_all
is renamed update_all_without_touch
. The new method modifies the upgrades
object to inject the update of updated_at
, and next call the original update_all
.
Upvotes: 7
Reputation: 4367
You can override the update_all method in your model:
def self.update_all(attr_hash) # override method
attr_hash[:updated_at] = Time.now.utc
super( attr_hash )
end
Upvotes: 2