2010-12-21 228 views
1

這與another question I asked recently存在一定的相關度。但在我實現這個問題的答案之前,我想嘗試以更簡單的方式做到這一點。訪問current_user評論過的所有帖子的所有評論

我已經在Rails應用程序上構建了一個ruby應用程序,允許用戶跟蹤他們的鍛鍊。鍛鍊也有能力進行評論。在我的current_user的儀表板視圖中,我試圖找出current_user評論過的所有鍛鍊評論。這裏是一個例子:

用戶A創建一個鍛鍊和用戶B評論它。用戶C對用戶A的鍛鍊進行評論。我希望用戶B在其儀表板視圖中查看用戶C的評論。

什麼是最有效的方式來循環評論和拉出用戶評論的鍛鍊的所有評論?這就像我想這樣說,但顯然這是行不通的:

<% current_user.comments.workouts.comments.each do |comment| %> 

我一直named_scopes這個實驗,但似乎無法推測出來。這些協會是你所期望的。

User has_many :workouts 
User has_many :comments 

Workout belongs_to :user 
Workout has_many :comments 

Comment belongs_to :user 
Comment belongs_to :workout 

回答

1

正如你可能要根據組織的用戶已經談到了鍛鍊的評論意見(相對於沒有任何上下文的長長的無差異評論串),首先我建議使用:has_many => through來彙總用戶評論過的訓練,大致類似(未經測試,顯然):

has_many :commented_workouts, :through => :comments, :class_name => 'Workout', :source => :workout, :uniq => true, :order => "created_at desc" 

然後,你可以顯示在您的ERB類似的意見:

<% current_user.commented_workouts.each do |workout| %> 
    <%= workout.name %>: 
    <% workout.comments.each do |comment| %> 
    <%= comment.text %> 
    <% end %> 
<% end %> 

編輯:你也可以這樣做:

<% current_user.commented_workouts.each do |workout| %> 
    <% workout.comments.sort{|x,y| x.created_at <=> y.created_at }.each do |comment| %> 
    <%= comment.user.name %> just commented on <%= workout.title %>: 
    <div><%= comment.text %></div> 
    <% end %> 
<% end %> 

編輯:或者像這樣(注意限制加入到陣列):

class User 
    def watched_comments 
    commented_workouts.map(&:comments).flatten.sort{|x,y| x.created_at <=> y.created_at } 
    end 
end 

# and in the erb: 

<% current_user.watched_comments[0,10].each do |comment| %> 
    <%= comment.user.name %> just commented on <%= comment.workout.title %>: 
    <div><%= comment.text %></div> 
<% end %> 

有一些令人討厭的n + 1查詢福去h這可能不是真正的高性能。或者,你可以嘗試讓所有的事情都做得更好。喜歡的東西(SQL忍者無疑會做的更好):

編輯:您也可以直接在SQL

has_many :watched_comments, :class_name => 'Comment', :finder_sql => 'select * from comments, workouts where comments.workout_id = workout.id and workouts.id in (select workouts.id from workouts, comments where workouts.id = comments.id and comments.user_id = #{id}) order by comments.created_at desc limit 10' 
0

喜歡的東西

<% workouts = [] 
    current_user.comments.each do |comment| 
    unless workouts.include? comment.workout.id # prevents duplicates 
     workouts << comment.workout.id 
     comment.workout.comments.each do |comment| 
     # now comment refers to all comments for that workout 
     puts "#{comment.user.name} says #{comment.text}" 
     end 
    end 
    end %> 

從本質上講,你抓住每他們的意見,並顯示他們所有的意見相關的鍛鍊。

對於額外的功課;)

  1. 標誌自己的一些特別的東西
+0

不就是導致重複添加一個「限制」選項? (讓我這樣說吧...如果鍛鍊A有2條評論由用戶1,則鍛鍊A的評論將循環兩遍!) – 2010-12-21 23:18:09

+0

我在額外的作業下寫道。你是對的。 – 2010-12-21 23:21:01

+0

我更新了代碼以防止重複。 – 2010-12-21 23:25:07

0
class User < ActiveRecord::Base 

    has_many :workouts 
    has_many :comments 

    def workouts_on_which_i_commented 
    comments.map{|x|x.workout}.uniq 
    end 

    def comment_stream 
    workouts_on_which_i_commented.map do |w| 
     w.comments 
    end.flatten.sort{|x,y| y.created_at <=> x.created_at} 
    end 

end 
相關問題