0

Rails 3 のデータベース クエリに 2 つのフィルターを適用しようとしています。最初のフィルターは、イメージ タイプのメディアのみを表示します。2 番目のフィルターは、最高の敬礼記事を表示します。フィルター自体は正常に機能しますが、両方のフィルターを組み合わせようとするとエラーが発生します。

関連する 3 つのテーブルがあります。物語、思い出、そして敬礼。敬礼テーブルは、誰かが思い出に「敬礼」した回数を追跡します。それぞれの物語は、複数の記憶から構成されています。ストーリーの総敬礼は、そのストーリーの思い出の敬礼の合計です。画像のみのストーリーのレコードを、敬礼の高い順に検索したいと考えています。

models/story.rb

def self.where_contains_image()
  joins(
    'INNER JOIN memories AS wci_memories ON wci_memories.story_id = stories.id'
  )
  .where(
    'wci_memories.media_type_cd = ?', Memory.image
  ).uniq
end

コントローラー/ストーリー_コントローラー.rb

if params[:filter_content] == 'image'
  stories = stories.where_contains_image
end

if (params[:filter_trends] == 'most_saluted')
  stories = stories.order("(SELECT COUNT(1) FROM salutes
    LEFT JOIN memories AS ms_memories ON salutes.content_id = ms_memories.id
    LEFT JOIN stories AS ms_stories ON ms_stories.id = ms_memories.story_id
    WHERE ms_stories.id = stories.id AND salutes.content_type = 'Memory')
    DESC");
end

「most_saluted」パラメーターが設定されている場合、クエリは期待どおりに機能します。「most_saluted」パラメーターと「image」パラメーターの両方が設定されていると、エラーが発生します。

for SELECT DISTINCT, ORDER BY expressions must appear in select list

エラーの内容は理解していますが、最も敬礼された順に画像のみを返すようにクエリを書き直す方法がわかりません。

データベースでこの SQL クエリを実行すると、探しているレコードが返されます。しかし、レールに同じレコードを返す方法がわかりません。さらに、このクエリは 2 つのフィルター (画像のみと最高の敬礼) を結合します。1 つのフィルターを個別に、または両方を一緒に適用できるように、それらを別々に保持したいと考えています。

SELECT DISTINCT stories.*, (SELECT COUNT(1) FROM salutes
    LEFT JOIN memories AS ms_memories ON salutes.content_id = ms_memories.id
    LEFT JOIN stories AS ms_stories ON ms_stories.id = ms_memories.story_id
    WHERE ms_stories.id = stories.id AND salutes.content_type = 'Memory') 
AS total_salutes FROM stories INNER JOIN memories AS wci_memories 
ON wci_memories.story_id = stories.id WHERE wci_memories.media_type_cd = 0
ORDER BY total_salutes DESC

これを解決する方法について何か考えはありますか?

4

1 に答える 1

0

スコープを使用してこれを実現できます。実際には、Activerecord スコープは、条件をチェーンするためのよりクリーンでモジュール化された方法です。

スコープについてはこちらをお読みください

HTH

于 2013-01-03T22:00:30.163 に答える