2012-07-07 88 views
2

用戶可以提交資源並發表評論。按關聯記錄的數量排序記錄

我想通過選擇已提交資源和評論的用戶來顯示最活躍的用戶,並將提交了最多資源和評論的用戶的結果排序爲最低。

**Resource** 
has_many :users, :through => :kits 
has_many :kits 
belongs_to :submitter, class_name: "User" 

**User** 
has_many :resources, :through => :kits 
has_many :kits 
has_many :submitted_resources, class_name: "Resource", foreign_key: "submitter_id" 

**Kits** 
belongs_to :resource 
belongs_to :user 

**Comments** 
belongs_to :user 

我是新來的這種sql在Rails中。我怎樣才能得到這個記錄集?

回答

2

首先,你需要將評論協會添加到用戶模式:

has_many :comments 

這樣,簡單的辦法是這樣做:

User.all.sort do |a,b| 
    (a.submitted_resources.count + a.comments.count) <=> (b.submitted_resources.count + b.comments.count) 
end 

這會變得非常慢,所以如果你想做得更好,你會想添加計數器緩存。在遷移:

def up 
    add_column :users, :submitted_resources_count, :integer 
    add_column :users, :comments_count, :integer 

    User.reset_column_information 

    User.find_each do |u| 
    u.update_attributes! \ 
     :submitted_resources_count => u.submitted_resources.count, 
     :comments_count => u.comments.count 
    end 
end 

def down 
    add_column :users, :submitted_resources_count 
    add_column :users, :comments_count 
end 

一旦運行這個遷移,你可以改變原來的查詢:

User.select('*, (submitted_resources_count + comments_count) AS activity_level').order('activity_level DESC') 

這將非常有效地恢復所有用戶以正確的順序,並作爲獎勵每個用戶將有一個名爲activity_level的只讀屬性,它將提供確切提交的資源+評論數。

+0

謝謝Tanzeeb,我有一個問題。 1. def-method中是否應該有remove_column:users,:submitted_resources_count? 2.我得知我運行這個遷移,但是User.find_each做的方法是| u |將僅在此次遷移時運行。那麼,我需要將它放在一個範圍內還是放在應用程序的其他位置,以便在我需要找到最活躍的用戶時運行? – chell 2012-07-16 15:03:17

+0

偉大的問題。 1)是的。 down方法應該撤消,因爲up會創建兩列,down應該刪除它們。 2)遷移中的更新設置了初始計數,但不需要再次調用。 Rails會自動更新匹配模式* _count的任何列與相應關聯的計數。您可以使用第三個查詢User.select ...作爲類方法或範圍來提取頂級用戶。將限制(1)添加到鏈的末尾以僅獲取頂級用戶。 – 2012-07-17 04:40:00