質問

プロジェクト内のコメントを追跡するためにポリモーフィックな関連付けを使用しています。どれも非常に単純明快なものばかりです。

私が抱えている問題は、ポリモーフィックな関連付けに基づいてクエリを実行し、コメント モデルからその所有者に結合することです。

それで ...

コメントモデルがあります

class Comment < ActiveRecord::Base
  belongs_to :commentable, :polymorphic => true
end

そして、ForumTopics モード:

class ForumTopic < ActiveRecord::Base
  has_many :comments, :as => :commentable
end

他にも「コメント可能な」モデルがいくつかありますが、現時点では重要ではありません。これはすべて機能します。

私がやろうとしているのは、指定された条件 (この場合は 'featured' == true) を持つ ForumTopic に属するすべてのコメントを検索することです。

ファインダーを使用してモデルを結合しようとすると、次のようになります。

@comments = Comment.find(:all 
            :joins => :commentable
            :conditions => ["forum_topics.featured = ? ", true] 
            )

次のエラーが表示されます。

多態性関連付けを熱心にロードできません:commentable

AR「インクルード構文」を使用する:

@comments = Comment.find(:all 
            :include => :forum_topics
            :conditions => ["forum_topics.featured = ? ", true] 
            )

戻り値:

「forum_topics」という名前の関連付けが見つかりませんでした。おそらくスペルを間違えましたか?

アソシエーション名の代わりにテーブル名(シンボルではなく文字列)を使用して結合しようとすると、次のようになります。

@comments = Comment.find(:all,
            :joins => "forum_topics",
            :conditions => ["forum_topics.featured = ? ", true] 
            )

なるほど:

Mysql::エラー:不明なテーブルの「コメント」:コメントを選択します。 FROM コメント forum_topics WHERE (forum_topics.featured = 1 )*

(ここで、基になるクエリの構文が完全に外れており、結合が完全に欠落していることがわかります)。

私がやっていることは可能かどうかさえわかりません、そして必要な結果を達成する他の方法はありますが、それはそうであるように思えます すべき 実行可能であること。

何か案は?何か足りないものはありますか?

役に立ちましたか?

解決

なんてこった!

私は、問題を見つけたと思う。

を経由して結合する場合:

@comments = Comment.find(:all,
        :joins => "forum_topics",
        :conditions => ["forum_topics.featured = ? ", true] 
        )

あなたは、全体が参加する必要があります!

:joins => "INNER JOIN forum_topics ON forum_topics.id = comments.commentable_id",

これまで、素晴らしいを参照してください。 http://guides.rubyonrails.org/active_record_querying.html#joining-tablesする

他のヒント

古い質問を、しかし多型と一緒に、特定のタイプのための直接的な関連を設定することによって、これを達成するためのクリーンな方法があります:

#comment.rb
class Comment < ActiveRecord::Base

  belongs_to :commentable, polymorphic: true
  belongs_to :forum_topics, -> { where( comments: { commentable_type: 'ForumTopic' } ).includes( :comments ) }, foreign_key: 'commentable_id'

  ...

end

あなたは参加し、その後汚いの必要性を取り除く:forum_topicsするincludesを渡すことができます:

@comments = Comment
  .includes( :forum_topics )
  .where( :forum_topics => { featured: true } )

あなたはその後さらにスコープにクエリを移動することで、これをクリーンアップすることができます:

#comment.rb
class Comment < ActiveRecord::Base

  ...

  scope :featured_topics, -> { 
    includes( :forum_topics )
    .where( :forum_topics => { featured: true } ) 
  }

  ...

end

タグだけで行うことができるようにあなたを残します
@comments = Comment.featured_topics

あなたは必要条件、プラスのRails 3 +

多くの人が回答やコメント欄でそれに言及したが、私は自分自身を含め、人々は、私がここに上陸した場合、最大つまずいになるだろうし、完全に十分読んでいないことを感じました。

だから、ここの絶対の必要がある条件を含む適切な答えは、です。

@comments = Comment.joins( "INNER JOIN forum_topics ON comments.commentable_id = forum_topics.id" )
                   .where( comments:     { commentable_type: 'ForumTopic' } )
                   .where( forum_topics: { featured:         true         } )

の彼らのコメントのためのすべてのおかげで、特に@Jits、@Peter、および@prograils。

あなたは「commentable」を使用して関連性を持っている別のモデルを紹介した後、

受け入れソリューションは動作しません。 commentable_idが一意でないため、間違ったコメントの取得を開始します。

は、

...コメントを受け付けニュースのモデルを追加することを決定します
class News < ActiveRecord::Base
   has_many :comments, :as => :commentable
end
あなたは1のIDと1のIDは、クエリを使用したとのニュース記事でforum_topicにコメントをした場合は、

今、あなたは二つのレコード取り戻すことがあります:

:joins => "INNER JOIN forum_topics ON forum_topics.id = comments.commentable_id"

あなたはおそらくあなたの条件の一つとしてcommentable_typeを供給することによってこの問題を解決することができますが、私はそれがこの問題にアプローチする最良の方法だとは思わない。

私はこの記事に出くわしたし、それは私のソリューションに私をリードしています。私の条件の一つとしてcommentable_typeを使用したが、LEFT OUTERを使用する代わりに、登録しよう。そのようにコメントなしフォーラムのトピックが含まれます。

LEFT OUTER JOIN `comments` ON `comments`.`commentable_id` = `forum_topics`.`id` AND `comments`.`commentable_type` = 'ForumTopic'

以下で動作するようにチェックされています レール5:

解決策 1:

@comments = Comment
              .where(commentable_type: "ForumTopic")
              .joins("INNER JOIN forum_topics ON comments.commentable_id = forum_topics.id")
              .where(forum_topics: {featured: true})
              .all

または

解決策 2:

@comments = Comment
              .joins("INNER JOIN forum_topics ON comments.commentable_id = forum_topics.id AND comments.commentable_type = 'ForumTopic'")
              .where(forum_topics: {featured: true}).all

生の SQL 構文に注意してください。バッククォートは使用できません。見る http://guides.rubyonrails.org/active_record_querying.html#joining-tables .

個人的には、生の SQL 構文が少ないため、解決策 1 の方が好みです。

Railsは多型がデフォルトで加入含まれていませんが、この宝石は、あなたが簡単にあなたの多型の関係に参加するために役立つだろう。 https://github.com/jameshuynh/polymorphic_joinする

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top