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

时间:2009-09-13 16:06:25

标签: ruby-on-rails activerecord

我有一个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

我的应用程序用于将应用程序数据库导出到包含非规范化数据版本的第二个数据库,包括collation_name作为实际列。我想使用collation_name命令记录在应用程序的视图中显示。我尝试了Foo.all(:order=>:collation_name),但得到了“没有这样的列:collat​​ion_name”错误。

如何获取Foo订购的collation_name条记录列表?我是否必须在ActiveRecord的应用程序数据库中添加collation_name作为实际列才能在订购时查看它?我应该在ActiveRecord返回结果后对我的应用程序代码进行排序吗?

2 个答案:

答案 0 :(得分:3)

如果您只需要在应用程序内部处理有限数量的行,请执行以下操作:

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查询视图)
  • 计算数据并将其存储在数据库中(对其进行非规范化,就像你说的那样)

答案 1 :(得分:1)

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

从您的问题来看,我不确定您的数据库是怎样的,因此无法辨别您可以使用哪个列:order。如果由rails构建的sql查询无法达到您期望的顺序,则可能必须使用ruby对.all方法的结果数组进行排序。