2012-04-26 8 views
0

私は候補者と候補者が多くの投票を持つシナリオを持っています。私は最高位から順番に候補者を注文したい。このクエリでは、というん:私の問題は、私はそれをレンダリングするためにこれを使用することである各子供の個別の質問を取り除くことの問題

Candidate.joins(:votes). 
    select(['candidates.*', 'SUM(votes.score) as total_score']).group('candidates.id, candidates.candidate_id, candidates.user_id, candidates.status, candidates.card_id, candidates.created_at, candidates.updated_at'). 
    order('candidates.status desc, total_score desc, candidates.created_at asc').where("candidates.riding_id = ? and candidates.status != ?", 124, CandidateStatus::Eligible). 
    having('SUM(votes.score) >= 0') 

render :json => @candidates.to_json(:include => [:votes]) 

これはその後、彼らの票を得るために、各候補者のためのクエリが発生します。私は1つのクエリでこれを行うことができるはずですが、どのように私がそれを変更しても、それはまだそれぞれの候補者を別々につかむ。

答えて

0

時には、#to_jsonが呼び出されるまで、投票が再度フェッチされなければならず、したがって追加のクエリがそれぞれ必要です。熱心なロードを使用して、しかし、それは追加のクエリせずにこれを実行することが可能です:

Candidate.all(:include => :votes).to_json(:include => [:votes]) 

したがって、それは熱心なローディングを含む@candidatesで行うことができる、など:

@candidates = Candidate.all(:include => :votes) 

@candidates.to_json(:include => [:votes]) 
+0

ドキュメントが言います.joins(:votes)を使用することは今すぐインクルードする適切な方法です。いずれにしてもどちらもうまくいきません - .allを行うときにはうまくいくかもしれませんが、それは投票や集計の必要性の要件を満たしていません。 – Codezy

+0

@Codezy: 'join 'は' include'と同じではなく、すべての場合に 'include'を取り替えています。私が理解している限りはそうです(http://railscasts.com/episodes/181-include-vs-joins )。 'include'は参照されたテーブルの属性をメモリにロードし、' joins'はSQL JOINを実行します(これはビルドされたクエリの '.to_sql'メソッドを使って調べることができます)。この場合、おそらく 'include'が必要なのではないかと思います。上記のクエリをテストしている間に、複数のクエリが生成されることはありません。しかし、もっとうまくいくかもしれません。 – tiredpixel

+0

@Codezy:ああ、それはRails 3の名前が 'includes'に変更され、' .includes'構造も存在するようです。あなたが言及した特定のコードについては、おそらく '.joins'を' .includes'に変更するだけです(あなたの特定のクエリをテストすることはできませんし、すべてのモデルを設定する必要はありません)。しかし、あなたがこれをやっているところを慎重に考え、必要以上に頻繁に使用しないことが重要です。なぜなら、通常のクエリの 'join 'よりも効率が低いからです。 – tiredpixel

関連する問題