2009-07-02 47 views
8

我想知道是否有一種有效的方法來結合Rails中的多個ActiveRecord對象的結果。例如,我可能會對三個單獨的表格進行三次單獨調用,並且希望將結果合併起來,並按共同列進行排序。如何結合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」列作爲日期?

回答

2

您不使用「表」,而是使用對象。

如果你仔細想想這樣,那就沒有什麼意義有:

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

什麼會的「組合拳」形式的意思嗎?

你可能想要的是使用不同的「查詢」組合相同結果的結果。 是嗎?

+0

我有一個用例,組合註釋,狀態和提交問題管理應用程序中的時間軸。 – dangerousdave 2012-10-23 18:24:26

+0

在這種情況下,他們必須全部響應特定的接口或有一種方法被映射到一個。關鍵在於,用「數據庫表」思考它會導致你陷入糟糕的設計。我並不是想暗示你不使用來自不同地方的數據,只是質疑你如何接近/思考它。 – 2012-10-25 15:58:35

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 } 
+0

如果我想按日期進行排序,但是Table3將「created_on」列引用爲日期,該怎麼辦?十分感謝! – Jess 2009-07-02 18:07:56

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) 

如果我想按日期排序,但表3是指「created_on」列中的日期?

class Table3 
    alias_method :date, :created_on 
end 

或者乾脆

class Table3 
    alias date created_on 
end 
0

我不知道你的數據量是什麼樣的,但是當涉及到排序,您的數據庫會比你曾經將利用「它的一個更好的工作應用層「代碼。

您是否需要將數據作爲模型對象數組返回,因爲三個表可能會生成三個不同模型類的混合數組?

爲什麼不使用直接SQL返回行和列,並讓數據庫完成所有艱難的數據排序工作?

1

你可能不會喜歡這個答案,但我會說你可能想要修改你的數據庫模式。我處於類似的情況,並且在將它們連接起來後對結果進行排序絕對不是您想要的方式。

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