ruby-on-rails - 按照给定 ID 数组的顺序按 ID 查找模型记录

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

我有一个查询要按特定顺序获取人员的 ID,例如: ids = [1,3,5,9,6,2]

然后我想通过 Person.find(ids) 获取这些人

但它们总是按数字顺序获取,我通过执行以下操作知道这一点:

people = Person.find(ids).map(&:id)
 => [1, 2, 3, 5, 6, 9]

如何运行此查询以使顺序与 ids 数组的顺序相同?

我让这个任务变得更加困难,因为我只想执行一次查询,从给定的 ID 中获取人员。因此,执行多个查询是不可能的。

我尝试过类似的方法:

ids.each do |i|
  person = people.where('id = ?', i)

但我认为这行不通。

最佳答案

Editor's note:
As of Rails 5, find returns the records in the same order as the provided IDs (docs).

此代码的注释:

ids.each do |i|
  person = people.where('id = ?', i)

它有两个问题:

首先,#each 方法返回它迭代的数组,因此您只需取回 id。你想要的是一个收集

其次,where 将返回一个 Arel::Relation 对象,该对象最终将作为数组进行计算。所以你最终会得到一个数组的数组。您可以通过两种方式修复。

第一种方法是展平:

ids.collect {|i| Person.where('id => ?', i) }.flatten

更好的版本:

ids.collect {|i| Person.where(:id => i) }.flatten

第二种方法是简单地进行查找:

ids.collect {|i| Person.find(i) }

这很好,也很简单

但是,您会发现这些都为每次迭代执行一次查询,因此效率不高。

我喜欢 Sergio 的解决方案,但这是我建议的另一个解决方案:

people_by_id = Person.find(ids).index_by(&:id) # Gives you a hash indexed by ID
ids.collect {|id| people_by_id[id] }

我发誓我记得 ActiveRecord 曾经为我们做过这个 ID 排序。也许它会随着阿雷尔一起消失;)

关于ruby-on-rails - 按照给定 ID 数组的顺序按 ID 查找模型记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10150152/

相关文章:

ruby-on-rails - rails : OR where condition on association

ruby-on-rails - 如何将 Postgres JSON 值放入 Rails 夹具中?

ruby-on-rails - Rails Assets 管道在开发中连接 application.css 和 js,但在生产中不连接

sql - 复杂的 Rails 查询 - 联合?子选择?我还能使用 named_scope 吗?

ruby-on-rails - ActiveRecord 事务没有回滚整个事务

ruby-on-rails - rails : Multiple parameters before do?

ruby-on-rails - Windows 上的 Rails 5 Puma 20 分钟后进入休眠状态

ruby-on-rails - 如何根据用户当前时区制作今天的日期方法?

ruby-on-rails - 如何在 Active Record/Rails 4 迁移中创建具有唯一索引的新表

ruby-on-rails - 为 Rails 对象创建临时属性并传递给 View