【问题标题】:Overriding update_all method for specific models Rails 4.2覆盖特定模型 Rails 4.2 的 update_all 方法
【发布时间】:2015-03-10 00:35:57
【问题描述】:

我需要重写 rails update_all 方法,以便它会更新特定模型的 updated_at 字段。

我在 app/config/initializer/xyzfile.rb 中添加了以下模块:

module ActiveRecord
  class Relation
    def update_all_with_updated_at(updates)
      case updates
        when Hash
          updates.reverse_merge!(updated_at: Time.now)
        when String
          updates += ", updated_at = '#{Time.now.to_s(:db)}'"
        when Array
          updates[0] += ', updated_at = ?'
          updates << Time.now
      end
      update_all_without_updated_at(updates)
    end
    alias_method_chain :update_all, :updated_at
  end
end

我想将它用于特定型号,我该怎么做?

  • 在每个 update_all 中添加 updated_at 是一种解决方案,但我正在寻找一种可以覆盖 update_all 方法的解决方案。

【问题讨论】:

  • 为什么不直接使用updated_at: Time.zone.now 调用update_all 方法(或将其添加到现有哈希中)?
  • @JiříPospíšil 这是解决方案之一。但是有了这个,我需要在所有需要的模型的每个 update_all 语句中添加 updated_at 。所以我正在寻找一个可以覆盖 update_all 方法的解决方案。

标签: ruby-on-rails ruby update-all activerecord-relation


【解决方案1】:

将以下代码放入文件 /config/initializers/update_all_with_touch.rb 把这段代码放在

app/config/initializer/update_all_decorate.rb

class ActiveRecord::Relation

  def update_all_decorate(updates, conditions = nil, options = {})

    current_time = Time.now

    # Inject the 'updated_at' column into the updates
    case updates
      when Hash;   updates.merge!(updated_at: current_time)
      when String; updates += ", updated_at = '#{current_time.to_s(:db)}'"
      when Array;  updates[0] += ', updated_at = ?'; updates << current_time
    end

  end
  alias_method_chain :update_all, :touch
end

alias_method_chain 块负责覆盖 update_all 方法的默认行为。

【讨论】:

  • 我添加了与此类似的代码,但我想为特定模型而不是全部覆盖 update_all 的行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-21
  • 1970-01-01
  • 2021-12-14
  • 2021-06-11
相关资源
最近更新 更多