Rails根据其他id更新多个记录

时间:2014-02-19 06:51:24

标签: ruby-on-rails ruby-on-rails-3 activerecord

使用Rails 3.2。如doc on update method所示,update根据id找到:

update(id, attributes)
# id - This should be the id or an array of ids to be updated.

# Updates multiple records
people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy" } }
Person.update(people.keys, people.values)

如果我想更新基于其他列找到的数组怎么办?例如:

people = { 'cook' => { "first_name" => "David" }, 'server' => { "first_name" => "Jeremy" } }

找到role = cook人,然后更新first_name = David;找到role = server人,然后更新first_name = jeremy

我希望在可能的情况下在1个查询中完成,而不是通过SQL完成。感谢。

3 个答案:

答案 0 :(得分:0)

您可以使用#update_all

实现此目标
people = { 'cook' => { "first_name" => "David" }, 'server' => { "first_name" => "Jeremy" } }

Person.update_all(people.keys, people.values)

答案 1 :(得分:0)

在这种情况下,我会编写自己的sql语句。我取决于您使用的是哪个数据库后端。

http://www.postgresql.org/docs/9.1/static/plpgsql-control-structures.html https://dev.mysql.com/doc/refman/5.0/en/case.html

答案 2 :(得分:0)

传递一组id和值时,update方法不会执行1个SQL查询。如果您查看update的源代码,您将看到它遍历数组并对每条记录执行2次查询(查找和更新查询),然后返回更新对象的数组。

如果您很高兴接受每行需要进行2次查询,那么您可以使用以下代码按角色查找人员。

people = { 'cook' => { "first_name" => "David" }, 'server' => { "first_name" => "Jeremy" } }

updated_people = people.keys.map.with_index do |role, index| 
  object = Person.where(role: role).first!
  object.update(people.values[index])
  object
end

注意:此代码仅更新每个角色找到的第一条记录,因为我假设只有一位厨师的名字为“大卫”。

如果你只想使用1个SQL语句,你应该像在devanand建议的那样在SQL中进行。