2011-08-16 36 views
1

在我的應用程序用戶寄存器活動,這屬於。註冊在註冊模型中進行管理,該模型具有名爲'參加'的布爾字段。Rails3:左連接聚合計數 - 如何計算?

我在嘗試生成排行榜並需要知道:每個用戶的註冊總數以及每個單獨事件流中用戶註冊的數量。

我想這(在User.rb):

# returns an array of users and their attendence count 
def self.attendance_counts 
    User.all( 
     :select => "users.*, sum(attended) as attendance_count", 
     :joins => 'left join `registrations` ON registrations.user_id = users.id', 
     :group => 'registrations.user_id', 
     :order => 'attendance_count DESC' 
    ) 
end 

生成的SQL適用於只是返回總參加數爲每個用戶,當我在數據庫中運行它,但所有的得到恢復是Rails中的用戶記錄。

我即將放棄並硬編碼每個流的counter_cache(它們相當固定)到用戶表中,只要在註冊模型保存上參加屬性更改時手動更新它。

不過,我很好奇如何執行這樣的查詢。在計算關係記錄的統計和報告時,它一定會出現。

你的時間和考慮是非常感謝。提前致謝。

回答

6

首先作爲一些關於style和rails函數的點來幫助您構建數據庫查詢。

1)你更好的寫作這是一個範圍,而不是即

scope attendance_counts, select("users.*, sum(attended) as attendance_count").joins(:registrations).group('registrations.user_id').order('attendance_count DESC') 

2的方法),這是最好不要打電話給所有的/發現/先上查詢,你已經建立了,直到你真正需要它(即在控制器或視圖中)。這樣,如果您決定稍後實施動作/片段緩存,則在緩存的動作/片段被提供給用戶時,將不會調用數據庫查詢。

3)Rails有一系列函數來幫助彙總db數據。例如,如果你只需要一個用戶ID和出席,你可以使用類似下面的代碼的總和:在回答

Registrations.group(:user_id).sum(:attended) 

其他功能包括:countavgminimummaximum

最後你的問題,rails將爲您創建一個屬性,以便訪問您在查詢的選擇部分中具有的任何自定義字段的值。例如

@users = User.attendance_counts 
@users[0].attendance_count # The attendance count for the first user returned by the query 
+0

謝謝各位。我仍然必須使用原始連接sql來獲取0(好,空)的記錄,但最後一部分通過模型訪問自定義字段非常有用。 – manafire