2010-12-21 221 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 
相关问题