Rails,ActiveRecord,在int数组中查询id,保持传递数组的顺序

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Rails,ActiveRecord,在int数组中查询id,保持传递数组的顺序相关的知识,希望对你有一定的参考价值。

我正在考虑解决问题的最佳方案。假设我们有一个ActiveRecord模型的ID列表:

ids = [1, 100, 5, 30, 4, 2, 88, 44]

然后我想进行查询,选择所有用户,例如列表中的ID,但保持订单。如果我做

User.where(id: ids)

响应将是具有asc order by id的用户列表,但我希望订单与数组中的顺序相同。

您认为这是最好的解决方案吗?选择所有用户,然后操作ActiveRecord对象列表?也许有一种更聪明的方法可以做到这一点。

谢谢!

答案

对于postgresql,参考here

User.where(id: ids).order("position(id::text in '#{ids.join(',')}')")
另一答案

如果您使用的是mysql,可以使用FIELD来订购结果:

class User < ActiveRecord::Base
  def self.find_in_order(ids)
    self.where(id: ids).order("FIELD(id, #{ids.join(',')})")
  end
end

User.find_in_order([1, 100, 5, 30, 4, 2, 88, 44])
另一答案

无论MySQL和Postgresql如何,如果你有一个小的id,

User.where(id: ids).sort_by { |u| ids.index(u.id) }
另一答案

如果你使用的是Postgres,你可以使用intarray

class User < ActiveRecord::Base
  def self.find_in_order(ids)
    self.where(id: ids).order("idx(array[#{ids.join(',')}], id)")
  end
end

你应该先启动模块

CREATE EXTENSION intarray
另一答案
users_by_id = User.find(ids).index_by(&:id) # Gives you a hash indexed by ID
ids.collect {|id| users_by_id[id] }
另一答案

Postgres的另一种可能性(9.4或更高版本):

ordered_ids = [1, 100, 5, 30, 4, 2, 88, 44]
User.joins("join unnest('{#{ordered_ids.join(',')}}'::int[]) WITH " 
           "ORDINALITY t(id, ord) USING (id)").reorder('t.ord')

请注意,重新排序非常重要。

基于https://stackoverflow.com/a/35456954的解决方案

以上是关于Rails,ActiveRecord,在int数组中查询id,保持传递数组的顺序的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Rails 中的查询中排除 id 数组(使用 ActiveRecord)?

Ruby On Rails 5,activerecord query其中模型关联id包括数组中的所有id

Rails/ActiveRecord order by Array

如何毫无例外地选择Array Rails ActiveRecord中的ID

Ruby on Rails - 使用符号数组获取对象关联值

Rails 5:ActiveRecord OR 查询