【问题标题】:rails array maintain order [duplicate]rails数组维护顺序[重复]
【发布时间】:2018-06-16 04:44:36
【问题描述】:

使用硬编码数组

array = [30,29,31,13,10,12,6,7,8,9,11]

尝试执行查询

 @pick = Item.where('id IN (?)', array).to_a

选择的Item的顺序如何保持初始数组的顺序?

【问题讨论】:

标签: ruby-on-rails arrays ruby


【解决方案1】:

假设您在单个请求中获取所有项目(即没有分页),那么您可以在使用初始数组中的索引获取项目后对项目进行排序,例如

@pick = Item.where('id IN (?)', array).sort_by do |item|
  array.index(item.id)
end

【讨论】:

  • 我很欣赏它的简洁性!但这是思路,使用数组的索引。
【解决方案2】:

告诉数据库首选顺序并直接从数据库中加载按该顺序排序的所有记录,而不是在 Ruby 中对记录进行排序,这是一种很好的方法。

将以下扩展添加到您的应用程序中:

# e.g. in config/initializers/find_by_ordered_ids.rb
module FindByOrderedIdsActiveRecordExtension
  extend ActiveSupport::Concern

  module ClassMethods
    def find_ordered(ids)
      order_clause = "CASE #{self.table_name}.id "
      ids.each_with_index do |id, index|
        order_clause << "WHEN #{id} THEN #{index} "
      end
      order_clause << "ELSE #{ids.length} END"

      where(id: ids).order(order_clause)
    end
  end
end

ActiveRecord::Base.include(FindByOrderedIdsActiveRecordExtension)

你可以这样写查询:

Item.find_ordered([2, 1, 3]) # => [2, 1, 3]

【讨论】:

  • 这是 IMO 的理智方法。不过,我可能会在 Rails5 中的 ApplicationRecord 中使用 include FindByOrderedIdsActiveRecordExtension
  • 我确实看到了这种方法的合理性。模块启动时出现错误ERROR: syntax error at or near "{"。我看不出建议的代码可以在哪里关闭!
  • 很抱歉,我在find_ordered 方法的第一行中的{self.table_name} 前面漏掉了一个#。我更新了我的答案。
猜你喜欢
  • 2015-09-12
  • 2013-10-10
  • 2020-01-06
  • 2011-02-27
  • 1970-01-01
  • 2014-03-03
  • 1970-01-01
  • 1970-01-01
  • 2013-08-08
相关资源
最近更新 更多