2013-09-29 55 views

回答

4

将下面的代码在一个文件/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 

,只要您使用update_all它会自动添加参数:updated_at => Time.now

说明:

这个片段使用alias_method_chain覆盖的update_all默认:

alias_method_chain :update_all, :touch 

方法update_all由该方法update_all_with_touch代替我定义了,原来update_all被重命名update_all_without_touch。新方法修改upgrades对象以注入更新updated_at,然后再调用原始的update_all

+0

此解决方案的工作原理,但我不清楚这是如何工作。有什么方法update_all_without_updated_at或update_all_with_updated_at?此外,代码中使用了不同格式的update_all,因此这些更新可以是散列,或数组或字符串。我可以检查类型并合并一个散列的updated_at参数,这是可行的,但是当它的数组或字符串呢? –

+0

@ user523146我修改了片段来处理字符串和数组,并添加了一些解释。更新文件并重新启动服务器以查看更改。 – Baldrick

+0

为了澄清,我用'with_touch'替换了'with_updated_at'。 – Baldrick

1

您可以在模型覆盖update_all方法:

def self.update_all(attr_hash) # override method 
    attr_hash[:updated_at] = Time.now.utc 
    super(attr_hash) 
end 
+0

我需要这种行为在多个模型中,因此我正在寻找一种可以跨模型工作的方法。 –

+0

因此,添加一个ActiveRecord超类并将函数添加到那里。然后它将适用于您的所有型号 – user2503775