草庐IT

ruby-on-rails - Rails ActiveRecord - update_all : how to update multiple fields at once with mixed type of arguments

coder 2025-06-11 原文

我有一个用例,我想使用 ActiveRecord::Relation update_all 方法并指定要设置的几个字段。我使用 update_all 是因为可以更新很多条目,我不想将它们全部加载并一个一个地更新。

其中一些需要直接的 SQL SET 语句,例如因为我根据另一列的值设置一列。

是否有一个简单的语法与 update_all 一起使它可读,沿着这个 =>

MyModel.where(state: :foo).update_all([
  'timespent = timespent + 500',  # Can't be anything else than a SQL statement
  state: :bar,  # Regular Rails SQL interpolation
  updated_at: DateTime.current   
])

请注意,上面的语法不起作用,因为它会尝试查找占位符并替换值,因此 state::barupdated_at: DateTime.current被忽略。

对此的部分解决方案是将所有内容都转换为单个 SQL 语句字符串,如下所示,但我不太喜欢这样做,因为我需要弄清楚 SQL 语句,并且在使用 Rails 编码时有点太复杂了;):

MyModel.where(state: :foo).update_all([
  "timespent = timespent + 500",  # Can't be anything else than a SQL statement
  "state = 'bar'",
  "updated_at = NOW()"   # Needed to translate from Rails to PGSQL
].join(', '))

有人有优雅的解决方案吗?

谢谢!

最佳答案

update_all采用字符串、数组或散列(但不能混合搭配)。在数组的情况下,它需要 ActiveRecord 数组条件。所以你应该能够做这样的事情:

MyModel.where(state: :foo).update_all([
  'timespent = timespent + 500, state = ?, updated_at = ?',
  'bar',
  DateTime.current
])

关于ruby-on-rails - Rails ActiveRecord - update_all : how to update multiple fields at once with mixed type of arguments,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36697709/

有关ruby-on-rails - Rails ActiveRecord - update_all : how to update multiple fields at once with mixed type of arguments的更多相关文章

随机推荐