如何合并ActiveRecord对象?

8
我想知道在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个回答

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"列定义为date类型,怎么办?

class Table3
  alias_method :date, :created_on
end

或者简单地说

class Table3
  alias date created_on
end

2

你需要处理的是对象,而不是“表格”。

如果你这样考虑,那么以下内容就没有意义:

@results1 = Users.find(:all)
@results2 = Posts.find(:all)
@results3 = Comments.find(:all)

“combined”形式指的是什么?

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


我有一个使用案例,在问题管理应用程序中将注释、状态和提交合并为时间线。 - dangerousdave
在这种情况下,它们必须全部响应于一个特定的接口或者有一种映射到一个接口的方式。关键点是,如果你从“数据库表”的角度来考虑它,那么会导致设计不良。我并不是想暗示你不使用来自不同地方的数据,只是质疑你的处理/思考方式。 - Carlos Lima

1

你可能不会喜欢这个答案,但我建议你重新设计数据库模式。我曾经遇到过类似的情况,将结果连接后再排序绝对不是你想要的方式。


1
我相信你,但你能具體說明一下你是如何處理這種情況的嗎? - iterion

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

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

如果某些模型没有日期方法,我建议你创建一个。 这很容易。

def date
  created_on
end

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

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

如果我想按日期排序,但Table3将“created_on”列称为日期,该怎么办?非常感谢! - Jess
你可以通过在Table3中添加一个“date()”方法来解决这个问题,该方法返回“created_on”的值。 - Ethan

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 对象。


0

我不确定你的数据量是多少,但是在排序方面,你的数据库会比你使用“应用层”代码更好地完成它。

由于这三个表可能会生成三个不同模型类的混合数组,所以你需要将数据返回为模型对象数组吗?

为什么不使用直接SQL返回行和列,并让数据库完成所有繁重的数据排序工作呢?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接