【问题标题】:Active Records order by ids [duplicate]按 ID 排序的 Active Records [重复]
【发布时间】:2015-04-22 10:17:58
【问题描述】:

如果我有 ids: 1,2,3,4 的记录并希望以某种方式对它们进行排序,例如 1、4、2、3,我该怎么做?

我想是这样的,但它当然行不通。

Service.all.order(id: [1, 4, 2, 3])

【问题讨论】:

    标签: ruby-on-rails ruby sorting ruby-on-rails-4


    【解决方案1】:

    贾斯汀·韦斯两天前写了一封blog article about this problem

    告诉数据库首选顺序并直接从数据库加载按该顺序排序的所有记录似乎是一种好方法。来自他的blog article 的示例。

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

    # e.g. in config/initializers/find_by_ordered_ids.rb
    module FindByOrderedIdsActiveRecordExtension
      extend ActiveSupport::Concern
      module ClassMethods
        def find_ordered(ids)
          order_clause = "CASE 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)
    

    这将允许您编写这样的查询:

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

    【讨论】:

    • 嗯,现在find_by_ordered_ids.rb:1:in `&lt;top (required)&gt;': uninitialized constant Extensions (NameError)
    • @VitalyFry :我从原始示例中删除了命名空间。请重试。
    • 我建议您将order_clause = "CASE id " 替换为order_clause = "CASE #{self.table_name}.id "。这将防止在使用联接等时出现任何模棱两可的查询。
    【解决方案2】:
     order = [1,4,2,3]
     @services = []
       order.each do |id|
       @services << Services.find(id)
       end
    

    【讨论】:

    • 这是非常低效的,因为它会对数据库进行 N(数组的大小)查询,而不仅仅是一次。
    • 完全同意。 OP 没有提到他们是否关心会发生多少查询,或者他们是否会做超过示例中使用的 4 个查询。
    猜你喜欢
    • 1970-01-01
    • 2015-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多