如何组合ActiveRecord对象?

时间:2009-07-02 17:47:59

标签: ruby-on-rails ruby activerecord

我想知道是否有一种有效的方法来组合Rails中多个ActiveRecord对象的结果。例如,我可能会对三个单独的表进行三次单独调用,我希望将结果组合在一起,并按公共列进行排序。

这是一个超级基本的代码示例,希望能让我的问题更容易理解:

@results1 = Table1.find(:all)  
@results2 = Table2.find(:all)  
@results3 = Table3.find(:all)  

@combined_results_sorted_by_date_column = (how?)

正如其他人所建议的,这是问题的一个解决方案。

@combined_results = @result1 + @result2 + @result3
@combined_results.sort! {|x,y| x.date <=> y.date}

如果我想按日期排序,但Table3将“created_on”列称为日期,该怎么办?

7 个答案:

答案 0 :(得分:14)

@results1 = Table1.find(:all)
@results2 = Table2.find(:all)
@results3 = Table3.find(:all)

@combined_results_sorted_by_date_column =
   (@results1 + @results2 + @results3).sort_by(&:date)

如果我想按日期排序,但Table3将“created_on”列称为日期怎么办?

class Table3
  alias_method :date, :created_on
end

或只是

class Table3
  alias date created_on
end

答案 1 :(得分:2)

您不使用“Tables”而是使用对象。

如果以这种方式思考,那么:

是没有意义的
@results1 = Users.find(:all)
@results2 = Posts.find(:all)
@results3 = Comments.find(:all)

它的“组合”形式意味着什么?

您可能想要的是使用不同的“查询”组合相同类型的结果。 是吗?

答案 2 :(得分:1)

您可能不会喜欢这个答案,但我想说您可能想要修改数据库架构。我处于类似的情况,并在连接后对结果进行排序绝对不是你想要的方式。

答案 3 :(得分:0)

@combined_results = @result1 + @result2 + @result3
@combined_results.sort! {|x,y| x.date <=> y.date}

虽然这肯定不是世界上最有效的代码,但它可能正是您所需要的。

如果某些型号没有日期方法,我建议您创建一个。 它就像。

一样简单
def date
  created_on
end

答案 4 :(得分:0)

@results1 = Table1.find(:all)
@results2 = Table2.find(:all)
@results3 = Table3.find(:all) 

combined = (@results1 + @results2 + @results3).sort { |x, y| x.date <=> y.date }

答案 5 :(得分:0)

我不确定您的数据量是什么样的,但是在排序时,您的数据库将比使用“应用程序层”代码做得更好。

您是否需要将数据作为模型对象数组返回,因为这三个表可能会生成三个不同模型类的混合数组?

为什么不使用direct-SQL返回的行和列,并让DB完成对数据进行排序的所有辛苦工作?

答案 6 :(得分:0)

我假设你想要一个由三种不同类型的ActiveRecord对象组成的混合数组,按某种日期排序。

@array = (Bucket.all + Mop.all + Detergent.all).sort{|x,y| x.sort_by <==> y.sort_by}

由于您的sort_by字段对于每种对象类型都不同,您需要定义它。

class Bucket < ActiverRecord::Base
  def sort_by
    cleaned_on
  end
end

class Detergent < ActiverRecord::Base
  def sort_by
    purchased_on
  end
end

您可以使用UNION提取在单个查询中排序的所有数据,但是您不会从中获取AR对象。