2011-02-05 11 views
2

では3つのこちらのモデルを持っていますリストには、プロジェクトごとに未読のスレッドの数が表示されます。ここで大きな問題となるのは、ユーザーが複数のプロジェクト(すべてのユーザーが行う)を持っている場合、プロジェクトごとに1つずつ、いくつかのクエリでヒットすることです。In Rails - 複数のクエリを持つ1つのクエリを持つ方法今、私は、ユーザーのプロジェクトのリストを持っている</p> <ul> <li>プロジェクト</li> <li>スレッド(PROJECT_ID)</li> <li>thread_participations(thread_idは、読みブール)</li> </ul> <p>、および:

Railsを使用して1つのDBヒットでユーザーのプロジェクトごとに未読数を返すクエリを作成したいとします。ここで

は、私はビューで今日を使用しているものです:

<% @projects.each_with_index do |project, i| %> 
<%=project %>: <%= Thread.unread(current_user,project).count %> 
<% end %> 

、スレッドモデルで

scope :unread, lambda { |user,project| 
     includes(:project,:thread_participations).where(:project_id => project.id, :thread_participations => {:read => false, :user_id => user.id}) 
    } 

これを行う方法上の任意の提案?これはどんなモデルも住んでいるはずですか?ユーザーのモデルはプロジェクトやスレッド固有ではないので、おそらくユーザーのモデルですか?

おかげ

答えて

1

あり、このクエリを構造化する方法はいくつかあるが、ここでは1です。

これを1つのクエリで実行し、結果をループすることができます。私はまず、特定のユーザーの未読のスレッド参加のスコープを作成します。そして、スコープを使用し、すべてのスレッドとのプロジェクトが含まれ、グループのプロジェクトIDによって(あなたがそのプロジェクトの未読スレッドを取得しているように)、その後threads.idをカウントすることにより、未読スレッドの数を数える:

 
class ThreadParticipations 
    scope :unread, lambda{ |user| where(user_id: user.id, read: false) } 
end 

ThreadParticipations 
    .unread(current_user) 
    .includes(:thread => :project) 
    .group('projects.id') 
    .count('threads.id') 

=> { 10 => 15, 11 => 10 } 
# project(10) has 15 unread threads and project(11) has 10 unread threads 
+0

おかげで、私は100%を守っているかどうか分からないので、私に聞かせてください...なぜThreadParticipationsでは未読の範囲があり、今はThreadのようにありませんか?ちょっと興味があるんだけど。また、2番目のブロック(ThreadParticipations ).unread(current_user ...)ここに住んでいますか?コントローラ?thxs – AnApprentice

+0

もう1つ、範囲未読はproject_idでフィルタリングされていませんか? – AnApprentice

+0

project_idでフィルタリングしていない理由はすべてのユーザーのプロジェクトをクエリに含めることをお勧めします。project_idでフィルタリングすると、複数のクエリ(プロジェクトごとに1つ)を実行するという元の問題に戻ります。 –