访问current_user评论过的所有帖子的所有评论

时间:2010-12-21 22:34:20

标签: ruby-on-rails ruby associations

这与another question I asked recently有关。但在我实现该问题的答案之前,我想尝试以更简单的方式执行此操作。

我在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

3 个答案:

答案 0 :(得分:1)

由于您可能希望根据用户评论的训练来组织评论(而不是没有任何上下文的一个长的无差别的评论字符串),首先我建议使用:has_many =&gt;通过聚合用户评论过的锻炼,大致类似于(未经测试,显然):

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查询,这可能不是真正的性能。或者,您可以尝试在直接的SQL中完成所有操作,这样做会更好。像(sql ninjas无疑可以做得更好):

编辑:您还可以直接在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'

答案 1 :(得分: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. 用特别的东西标记自己的评论

答案 2 :(得分: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