使用#update_all更新时间戳

Gan*_*row 17 ruby ruby-on-rails ruby-on-rails-3

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

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

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

obj = MyObj.find(2)
obj.closed = false;
obj.save!
Run Code Online (Sandbox Code Playgroud)

在此语句后,updated_at字段更改值.为什么是这样?我updated_at在我的应用程序中依赖这个字段,因为我正在收听更新并在发生这种情况时整个应用程序流程?

编辑

我刚从dax答案中发现:

Timestamps

Note that ActiveRecord will not update the timestamp fields (updated_at/updated_on) when using update_all().
Run Code Online (Sandbox Code Playgroud)

我不想一次更新一条记录,有没有办法解决这个问题?不求助于sql级别?

kik*_*kik 36

#update_all 没有实例化模型.

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

编辑有关编辑:

如果您想保留"一个查询来统治它们",您可以更新updated_at以及:closed:

MyObj.where(:id => ids).update_all(closed: true, updated_at: DateTime.now)
Run Code Online (Sandbox Code Playgroud)

但请注意,验证仍未运行.

  • 为'一个查询来统治所有'的+1,这是一个更好的答案:) (2认同)
  • 不要使用 DateTime.now,使用 DateTime.current 它将使用应用程序的默认时区,默认为 UTC+00。DateTime.now 使用系统的时区。 (2认同)