2010-12-21 2 views
1

에 댓글을 달았습니다. 모든 게시물의 모든 댓글에 액세스합니다. another question I asked recently과 관련된 분류입니다. 하지만 그 질문의 답을 구현하기 전에 좀 더 간단한 방법으로 시도하고 싶었습니다.current_user가 (가)

나는 사용자가 운동을 추적 할 수있는 레일 응용 프로그램에 루비를 만들었습니다. 운동은 또한 댓글을 달 수있는 능력이 있습니다. current_user 대시 보드보기에서 나는 current_user가 주석을 달았습니다 모든 의견을 물고기 밖으로하려고합니다. 예를 들면 다음과 같습니다.

사용자 A는 운동을하고 사용자 B는 의견을 작성합니다. 사용자 A의 운동에 대한 사용자 C의 의견. 사용자 B가 대시 보드보기에서 사용자 C의 주석을 보도록합니다.

댓글을 반복하고 사용자가 댓글을 단 운동의 모든 댓글을 가져 오는 가장 효율적인 방법은 무엇입니까? 나는 이것에 대한 named_scopes 실험 한

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

하지만 그것을 알아낼 수없는 것 : 나는이 말을하고 싶지만 분명이 작동하지 않을 것입니다. 협회는 당신이 기대하는대로 있습니다.

<% 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 %> 

같은

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 =>를 사용하여 사용자가 주석 처리 한 운동을 집계하는 방법을 제안합니다. 대략적으로 (테스트되지 않은, 분명히) 비슷합니다.

당신은 또한 할 수있는 :

<% 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 %> 

편집 :

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

편집 :

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

는 그런 다음처럼 ERB 뭔가에 의견을 표시 할 수 또는과 같이 (한계에 추가주의 배열) :

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 %> 

h가 계속되는 불쾌한 n + 1 쿼리 fu가 있습니다. ere 그것은 진짜 performant tho일지도 모르지 않았다. 또는 당신은 모든 일을 더 잘 수행 할 수있는 바로 SQL로 처리하려고 할 수 있습니다. (의심의 여지가 더 잘 할 수있는 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

좋아,이 작품을하지만 실제로 의견의 단일 스트림 싶어요. 예를 들어, put은'UserA가 workouttitle에 댓글을 달았습니다 .' 코드를 수정하여 코드를 조정할 수 있습니까? – bgadoci

+0

아,': order => "created_at DESC"' – bgadoci

+0

확실히 편집하십시오. –

0

뭔가 본질적으로, 당신은 그들의 의견의 각 그들에 대한 모든 의견을 표시와 관련된 운동을 잡아.

여분의 숙제

)

  1. 신고 당신은 아마 사용자가 주석했던하여 운동에 따라 주석을 구성 할 것으로
+0

윌하지 그 원인 중복에 직접 '제한'옵션을 추가 할 수 있습니까? (내가이 방법으로 넣을 수 있도록 ...Workout A가 User1에 의해 2 개의 댓글을 가지고 있다면, Workout A의 코멘트는 두 번 반복됩니다!) –

+0

나는 여분의 숙제를 통해 그것을 썼습니다. 너 맞아. –

+0

중복을 막기 위해 코드를 업데이트했습니다. –

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 
+0

이것은 잘 작동하는 것 같습니다. 어떻게하면': limit => 3'과 같은 레코드의 수를 제한 할 수 있을까요? 또한,'created_at DESC' 명령. ? – bgadoci

+0

어떤 것을 제한 하시겠습니까? comment_stream의 댓글 순수는? 당신이 연결되어있는 운동 횟수? 배열 끝에서 "take"메서드를 사용하여 배열에서 반환 된 결과 수를 제한 할 수 있습니다. 위의 정렬은 이미 created_at을 기반으로합니다. 다른 정렬을 원할 경우 변경하십시오. –