Доступ ко всем комментариям, ко всем сообщениям, которые прокомментировал current_user - PullRequest
1 голос
/ 22 декабря 2010

Это как бы связано с другим вопросом, который я недавно задавал .Но прежде чем реализовать ответ на этот вопрос, я хотел бы попытаться сделать это более простым способом.

Я создал приложение ruby ​​on rails, которое позволяет пользователям отслеживать свои тренировки.Тренировки также имеют возможность комментировать.В моем представлении панели инструментов для current_user я пытаюсь найти все комментарии о тренировках, которые прокомментировал current_user.Вот пример:

Пользователь A создает тренировку, а Пользователь B комментирует ее.Пользователь C комментирует тренировки пользователя А.Я хочу, чтобы пользователь 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 ]

1 голос
/ 22 декабря 2010

Поскольку вы, вероятно, захотите организовать комментарии в соответствии с тренировками, которые прокомментировал пользователь (в отличие от одной длинной недифференцированной строки комментариев без какого-либо контекста), сначала я бы предложил использовать: has_many => throughчтобы объединить тренировки, которые прокомментировал пользователь, что-то вроде (непроверено, очевидно):

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

Тогда вы можете отобразить комментарии в своем эрбе что-то вроде:

<% 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, без сомнения, могло бы быть лучше):

EDIT: вы также можете добавить опцию 'limit' непосредственно в 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 голосов
/ 22 декабря 2010
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
0 голосов
/ 22 декабря 2010

Что-то вроде

<% 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. Пометить свой комментарий чем-то особенным
...