在不使用 update_all 和单个查询的情况下,在 rails 中进行批量/批量更新?

Rah*_*jha 6 sql activerecord ruby-on-rails

我想使用活动记录的单个查询更新多行。我不必使用 update_all 因为它跳过验证。有什么办法可以在 Rails 活动记录中做到这一点。?

Ale*_*nko 7

如果您想更新多个记录而不实例化模型,update_all方法应该可以解决问题:

\n
\n

使用给定的详细信息更新当前关系中的所有记录。此方法构造单个 SQL UPDATE 语句并将其直接发送到数据库。它不会实例化所涉及的模型,也不会触发 Active Record 回调或验证。但是,传递给 #update_all 的值仍将经过 Active Record\xe2\x80\x99 的正常类型转换和序列化。

\n
\n

例如:

\n
# Update all books with \'Rails\' in their title\nBook.where(\'title LIKE ?\', \'%Rails%\').update_all(author: \'David\')\n
Run Code Online (Sandbox Code Playgroud)\n

据我了解,它甚至接受一个数组作为参数,允许我们提供不同的哈希值以相应的顺序更新不同的记录,就像在 SQLUPDATE语句中一样。如果我错了,请纠正我。

\n

  • 它确实接受数组作为参数,但不允许您提供不同的哈希值来更新不同的记录。我无法弄清楚它到底是做什么的,所以我会避免那样使用它 =) (2认同)

Abd*_*sit 4

使用 activerecord-import gem 可以实现不使用 update_all 的批量更新。请参阅宝石以获取更多信息。方法详细

示例:假设有一个名为“Services”的表,其中有一个“booked”列。我们想使用循环外的 gem 来更新它的值。

services.each do |service| 
 service.booked = false 
 service.updated_at = DateTime.current if service.changed?
end


ProvidedService.import services.to_ary, on_duplicate_key_update: { columns: %i[booked updated_at] }
Run Code Online (Sandbox Code Playgroud)

默认情况下,active-record 导入不会更新“updated_at”列。所以我们必须明确地更新它。