2013-03-23 15 views
6

さて、 "トピック - 関係 - カテゴリ"があります。アクティブレコードとの関連付けによって、has_manyの関連するレコードが見つからないレコードを見つける方法はありますか?

つまり、Topicはhas_many categories through relationshipを持っています。

私はすべてのトピックカテゴリを持っているカテゴリ

#Relationship Model 
    Topic_id: integer 
    Category_id: integer 

    @topics=Topic.joins(:relationships) 

しかし、ではないとのことトピックを得るために、その非常に簡単だと思います。だからカテゴリがないトピックをどのように検索しますか? マイナスのクエリはありますか?

おそらくそれは@topics=Topic.where('id NOT IN (?)', Relationship.all) のように見えますが、これはactiverecord equivalent to SQL 'minus'にありますが、この解決策についてはわかりません。

+1

あなたは 'Topic.whereのようなもので、リストを取得できません(:?categories.nil)何がnilでない関係で見出されていないとき、' –

+0

ARは空の配列を返します。 – holaSenor

+0

@ tester123、私はしばらくDatamapperを使ってきました。 –

答えて

10

本当に関係としては良いでしょうか。これがうまくいくと思う:

@topics = Topic.joins('left join relationships on relationships.topic_id = topics.id').where('relationships.category_id is null') 

またはこの:

@topics = Topic 
    .joins('left join relationships on relationships.topic_id = topics.id join categories on categories.id = relationships.category_id') 
    .group('topics.id').having('count(categories.id) = 0') 
+0

ビンゴ、正解は左結合を使用することです –

0

これを試してください。カテゴリRelationオブジェクトの長さがゼロのトピックのみを選択してください。

@topics = Topic.all.select {|t| t.categories.length == 0 } 
+0

MrTheWalrusの答えはおそらくあなたのテーブルにいくつのトピックが存在するかによって、何度かアドホックチェックを行っているだけですが、これが頻繁に呼び出される場合は、3つのオプションすべてをベンチマークし、データベースを最も効率的に使用するオプションを選択する必要があります。 – holaSenor

+2

これは悪い解決策です。すべてのトピックをメモリに集め、すべてのトピックを個別にクエリします。これは、1つのクエリとして、Mr MrTheWalrusのソリューションとして実行できます。ほとんどの場合、データベースに実装できるロジックはすべてデータベースに実装する必要があります。そのはるかに高速かつはるかに多くのメモリとCPU効率。 – eirikir

+1

よろしくお願いいたします。うん、私たちが百万の話題を持っていると想像してください!、私は@MrTheWalrusの提案に行きます。 – holaSenor

0

私はincludesを使用することだと思う最も簡単な答えは、探していました。より正確であり、あなたがSQLを考えて取得

topics = Topic.includes(:relationships).where(relationships: {id: nil})

もう一つの方法は、LEFT OUTER JOINSです。

Topic.joins("LEFT OUTER JOINS relationships ON relationships.topic_id = topics.id") 
    .where(relationships: {id: nil}) 
関連する問題