2016-04-18 17 views
0

を修正するには、私は三つのモデルを持っています。Railsの - - イーガーロード2つのテーブルが、1をフィルタリングするN + 1

ユーザーに属するすべての送信先を示す表を作成しています。ユーザーは、その宛先の一部(ただしすべてではない)のレビューを残しました。

コントローラー:

@user = User.find_by_id(params[:id]) 
@user_reviews = @user.destination_reviews 

ビュー:

<% @user.destinations.each do |destination| %> 
    <% review = @user_reviews.find_by_destination_id(dest.id) %> 
    <% if review %> 
    <div class="review> 
     ...show the review 
    </div> 
    <% else %> 
    <div class="add-review> 
     ...prompt user to add a review 
    </div> 
    <% end %> 
<% end %> 

N + 1が@user_reviews.find_by_destination_id(dest.id)で起こっている、@user_reviewsは、ユーザのレビューのプリロードリストです。

ユーザーがこれらの宛先に残したレビューを含め、このユーザーに属するすべての送信先を読み込むにはどうすればよいですか?

私のようないくつかのクエリを探しています:

dest_ids = current_user.destinations.pluck(:id)` 
Destination.includes(:destination_reviews).where(id: dest_ids).where('destination_reviews.user_id = ?', user_id) 

しかし、それはエラーがスローされます:私はそれをせずに@user_reviews.find_by_destination_id(dest.id)を書くことができやり方があった場合、 ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: missing FROM-clause entry for table "destination_reviews"

また再照会データベース、それは動作します。

ことが明らかであるか、私は詳細に

答えて

1

を追加する必要がある場合、最も簡単な方法はgroup_byを使用するのであれば、私に知らせてください:

@user_reviews = @user.desintation_reviews.group_by(&:destination_id) 

、ビューに

<% review = @user_reviews[dest.id] %> 

ことユーザーの宛先を取得するためのクエリと、レビューを取得するクエリを提供します。

または一部がDestinationにいくつかの疑似属性を作成するために、selectを使用して、プラス参加すると、あなたは、単一のクエリにそれを得ることができ、その後、あなたはちょうどあなたがdestから必要なすべてのものを引き出すことができます。しかし、特にあなたがジョイン・テーブルを見ているので、もっと複雑になるでしょう。

current_user.destinations. 
      joins("LEFT OUTER JOIN destination_reviews r " + 
        "ON r.user_id = trips.user_id " + 
        "AND r.destination_id = destinations.id"). 
      select("destinations.*, r.foo AS review_foo, r.bar AS review_bar") 

してから、この:このような何か(テストしていない)ことになるだろう

<% if destination.review_foo %> 
+1

はあなたの先生ありがとうございました!だから 'group_by(&:destination_id)'は宛先IDをキーとしてハッシュを作成しますか? – CHawk

+0

正確です。基本的に 'find_by_destination_id'を使ってデータベースに何度も戻ってくるのではなく、それらをすべて前にロードしてから、ハッシュから正しいものを取得します。 –

関連する問題