Override rails update_all method

大城市里の小女人 提交于 2019-12-11 02:47:42

问题


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?


回答1:


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.




回答2:


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


来源:https://stackoverflow.com/questions/19076886/override-rails-update-all-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!