質問はRoRとして行われますが、クエリレベルについてはさらに多くの質問が当てはまります。すべての削除された関連付けを持つレコードのみを検索します
私はモデル
ModelA has_many ModelB
を持っていると私はそれらの両方でparanoid
宝石を使用しています。
私はModelB
が関連付けられていないのいずれかまたはそのすべてModelB
が(それゆえdeleted_at
がNULLでない)削除されたすべてのModelA
を見つけるためにしようとしています。
this questionに基づいて、私は望みの結果を得ることができましたが、クエリを読むことはそれがどのように動作しているかにはあまり意味がありません。
ModelA.joins('LEFT OUTER JOIN model_bs ON model_bs.model_a_id = model_as.id AND model_bs.deleted_at IS NULL')
.where('model_bs.model_a_id IS NULL')
.group(model_as.id)
私が使用している結合条件も後でwhere節でnullになるため、このクエリを読むとわかりません。
誰かが適切に設定されたクエリを得るのを手伝ってもらえますか?これが適切な方法であれば、正しい結果が得られたクエリの仕組みを教えてください。
アップデート:私は何が起こっていたかを理解するために管理し、いくつかの生のSQLの後、以下のコメントで述べたように
。また、それを破壊(少なくとも私の観点から)それをより明確にするよう
を私のARソリューションを書いた:
このクエリは、独立して、左側にすべてのモデルを返し、通常の左外部結合を表し、右側に関連がある場合。他だけModelA
で1行が返されます、関連するものがある場合
AND model_bs.deleted_at IS NULL
が利用可能ModelB
属性を持つ行を返します。参加するには、余分な条件を追加する
ModelA.joins('LEFT OUTER JOIN model_bs ON model_bs.model_a_id = model_as.id')
。
これらの行を適用すると、関連するモデルがない行だけが保持されます。
注:この場合 、動作します属性model_a_id
またはmodel_b
の他の属性を使用しますが、この道を行けば、私は関連が存在する場合、そのは常にになるだろうという属性を使用してお勧めしますそこ。そうしないと、結果が間違ってしまう可能性があります。最後に
、私は私が欲しかったものを翻訳するために使用して終わってきたAR:
ModelA.joins('LEFT OUTER JOIN model_bs ON model_bs.model_a_id = model_as.id AND model_bs.deleted_at IS NULL')
.group('model_as.id')
.having('count(model_bs.id) = 0')
私も同様の問題がありました。この回答を確認することができます:http://stackoverflow.com/a/15660222/580346 – mrzasa
ここに投稿した後、私は説明を探し続けました。 ARの代わりにraw SQLを少し使い、理由を理解するのを助けました。 – rpbaltazar