我有一个查询要按特定顺序获取人员的 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/