在Rails数据库中更新多个行,每个行都有唯一的值

时间:2018-11-05 01:10:17

标签: ruby-on-rails postgresql activerecord

我已经对此进行了广泛的研究,但似乎找不到所需的答案。

我熟悉Rails事务,但是在这种情况下,事务将执行多个查询,而我宁愿不这样做。

在单个查询中,如何用唯一值更新多行中的同一列?

例如:

update_hash =  {1: 'Bandits on the High Road', 2: 'Broccoli: The Menace'}
Books.where(<id_is_in_update_hash_keys>).each do |b|
  matching_hash_key = b.id
  new_title = update_hash[:matching_hash_key].value
  # problem here because each update is a query
  b.update(title: new_title)
end

当然,我可以将它包装在一个事务中,但是1万本书籍仍然调用1万个查询。我使用Postgresql,但是我不知道在单个查询中为多个对象更新该字段的正确,惯用方式。数据已经过预先审核,因此不再需要运行验证。

如果有人知道要执行的Rails代码,或者更可能需要生成的Postgresql查询,我将不胜感激。

1 个答案:

答案 0 :(得分:1)

使用PostgreSQL可以进行如下查询:

update_hash = { 1: 'Bandits on the High Road', 2: 'Broccoli: The Menace' }
values = update_hash.map { |k, v| "(#{k}, #{ActiveRecord::Base.connection.quote(v)})" }.join(', ')

query = "
    UPDATE books T
    SET title = uv.new_title
    FROM (VALUES #{values}) AS uv (id, new_title)
    WHERE T.id = uv.id::int"

ActiveRecord::Base.connection.execute(query)