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

use*_*922 16 ruby-on-rails ruby-on-rails-4

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

ids = [1, 100, 5, 30, 4, 2, 88, 44]
Run Code Online (Sandbox Code Playgroud)

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

User.where(id: ids)
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢!

Vic*_*Vic 14

参考这里,对于postgresql,

User.where(id: ids).order("position(id::text in '#{ids.join(',')}')")
Run Code Online (Sandbox Code Playgroud)


Bro*_*tse 9

如果您使用的是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])
Run Code Online (Sandbox Code Playgroud)


fen*_*ngd 6

如果您的ID较小,则应少考虑MySQL和Postgresql ,

User.where(id: ids).sort_by { |u| ids.index(u.id) }
Run Code Online (Sandbox Code Playgroud)

  • 这个答案很有效 - 我的评论不是批评,只是信息以防其他人遇到同样的问题。请注意,答案中使用的 `sort_by` 返回一个 `array`,而不是某些 gem(如我使用的分页 gem)需要正常工作的 `ActiveRecord_Relation` 对象。Vic 下面的答案对我有用,因为我使用的是 postgres 并且需要一个有序的 AR 关系。 (2认同)