代码之家  ›  专栏  ›  技术社区  ›  Will Harris

在ActiveRecord中查找按方法排序的所有行

  •  1
  • Will Harris  · 技术社区  · 17 年前

    我有一个ActiveRecord模型,它有一个名为 name (在数据库中)和一个名为 collation_name (不在数据库中)返回名称的简化版本。模型类类似于此:

    class Foo < ActiveRecord::Base
    
      # ... other stuff ...
    
      def collation_name
        words = name.downcase.split
        if words[0] == 'the'
          words.shift
        end
        words.join(' ')
      end
    end
    

    我的应用程序用于将应用程序数据库导出到第二个数据库,该数据库包含数据的非规范化版本,包括 排序规则名称 作为一个真正的专栏。我想用 排序规则名称 Foo.all(:order=>:collation_name) 但出现了“无此类列:排序规则名称”错误。

    我怎样才能得到一份清单 Foo 由订购的记录 排序规则名称 ? 我必须补充吗 作为ActiveRecord应用程序数据库中的真实列,在订购时是否可以查看它?我应该在ActiveRecord返回结果后对应用程序代码进行排序吗?

    2 回复  |  直到 17 年前
        1
  •  3
  •   yawn    17 年前

    如果您只需要处理有限数量的行,请在应用程序中进行如下排序:

    class Foo
    
      attr_accessor :name
    
      def initialize(name)
        self.name = name
      end
    
      def collation_name 
        name
      end
    
      def <=>(other)
        collation_name <=> other.collation_name
      end
    
    end
    
    # create 10 foos
    foos = Array.new(10).map { |e| Foo.new(rand(100_000).to_s) }
    p foos # foos are unsorted
    p foos.sort # foos are sorted 
    
    # alternative: use a closure to sort
    Foo.send :remove_method, '<=>'.to_sym
    p foos.sort { |a,b| a.collation_name <=> b.collation_name } # sorted again
    

    如果要使用ActiveRecord对结果集进行排序,则需要在数据库中显示该列。任何一个

    • 使用一个为您派生结果的函数(基本上与您在Ruby中使用的代码相同),并将其作为结果集的一部分(例如,将其放入视图中,然后使用:from查询视图)
        2
  •  1
  •   txwikinger    17 年前

    为了:为了工作,您必须使用由.all方法创建的查询中已知的列,或者必须重载类中的.all方法以添加缺少的功能。

    从您的问题来看,我不确定您的数据库是什么样子的,因此不清楚您可以使用哪一列:order。如果rails生成的sql查询无法达到预期的顺序,则可能必须使用ruby对.all方法的结果数组进行排序。