当我有要更新其属性的ID列表时,数据库中的updated_at
字段似乎没有变化,这就是我的意思:
ids = [2,4,51,124,33]
MyObj.where(:id => ids).update_all(:closed => true)
执行此更新后,updated_at
字段不会更改。但是,当我使用rails c
进入rails控制台并执行此操作时:
obj = MyObj.find(2)
obj.closed = false;
obj.save!
在此语句后updated_at
字段更改值。为什么是这样?我正在依赖我应用中的updated_at
字段,因为我正在收听更新并在发生这种情况时整个应用流程?
修改
我刚从dax
回答说:
Timestamps
Note that ActiveRecord will not update the timestamp fields (updated_at/updated_on) when using update_all().
我不想一次更新一条记录,有没有办法解决这个问题?不求助于sql级别?
答案 0 :(得分:35)
#update_all
does not instantiate models。
因此,它不会触发回调或验证 - 并且时间戳更新是在回调中进行的。
编辑有关编辑:
如果您想保留“一个查询来统治所有”,您可以更新updated_at以及:closed
:
MyObj.where(:id => ids).update_all(closed: true, updated_at: DateTime.now)
但请注意,验证仍未运行。
答案 1 :(得分:1)
全部更新,此方法构造单个SQL UPDATE语句并将其直接发送到数据库。它不会实例化所涉及的模型,也不会触发Active Record回调或验证。传递给update_all的值不会通过ActiveRecord的类型转换行为。它应该只接收可以按原样传递给SQL数据库的值。
因此,它不会触发回调或验证 - 并且时间戳更新是在回调中进行的.update_at是一个回调引用http://api.rubyonrails.org/classes/ActiveRecord/Relation.html#method-i-update_all
答案 2 :(得分:0)
时间戳
请注意,使用update_all()时,ActiveRecord不会更新时间戳字段(updated_at / updated_on)。
来源:http://apidock.com/rails/ActiveRecord/Relation/update_all
答案 3 :(得分:0)
如果有人感兴趣,我确实做了一个要点,概述了如何自己滚动。
https://gist.github.com/timm-oh/9b702a15f61a5dd20d5814b607dc411d
这是完成工作的超级简单的实现。 如果您觉得还有改进的余地,请评论要点:)