24

当我有要更新其属性的 id 列表时,updated_at数据库中的字段似乎没有改变,这就是我的意思:

ids = [2,4,51,124,33]
MyObj.where(:id => ids).update_all(:closed => true)

执行此更新后,updated_at字段不会更改。但是,当我进入 rails 控制台rails c并执行此操作时:

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级别?

4

4 回答 4

49

#update_all 不实例化模型

因此,它不会触发回调或验证 - 并且时间戳更新是在回调中进行的。

编辑关于编辑:

如果您想保留“一个查询来统治所有这些”,您可以更新 updated_at 以及:closed

MyObj.where(:id => ids).update_all(closed: true, updated_at: DateTime.now)

但请注意验证仍未运行。

于 2013-09-18T13:12:28.507 回答
1

全部更新,此方法构造单个 SQL UPDATE 语句并将其直接发送到数据库。它不会实例化涉及的模型,也不会触发 Active Record 回调或验证。传递给 update_all 的值不会通过 ActiveRecord 的类型转换行为。它应该只接收可以按原样传递给 SQL 数据库的值。

因此,它不会触发回调或验证 - 并且时间戳更新是在回调中进行的。update_at 是回调以供参考http://api.rubyonrails.org/classes/ActiveRecord/Relation.html#method-i-update_all

于 2015-01-07T07:06:32.343 回答
0

时间戳

请注意,ActiveRecord 在使用 update_all() 时不会更新时间戳字段 (updated_at/updated_on)。

来源:http ://apidock.com/rails/ActiveRecord/Relation/update_all

于 2013-09-18T13:11:02.580 回答
0

如果有人感兴趣,我确实做了一个要点,概述了如何自己滚动。

https://gist.github.com/timm-oh/9b702a15f61a5dd20d5814b607dc411d

这是一个超级简单的实现,只是为了完成工作。如果您觉得还有改进的余地,请评论要点:)

于 2020-03-05T12:50:24.180 回答