arel
の使用 かなり遠くまで行くことができます。トリッキーな部分は、arel
を使用してクエリ全体を記述しない方法です。 独自のクエリ構文?
秘訣は次のとおりです。where
を使用してクエリを作成する場合 、arel
を使用する場合 条件、あなたは無料でいくつかの追加のメソッドを取得します。たとえば、そこにあるサブクエリを.exists.not
で調整できます。 、(NOT ( EXISTS (subquery)))
を取得します それを親のwhere
に投げ込みます -節とあなたは準備ができています。
問題は、関係するテーブルをどのように参照するかということです。そのためにはアレルが必要です。あなたはできた Arelのwhere
を使用します a.eq b
のような醜い条件で 。しかし、なぜ?等式条件なので、代わりにRailsの条件を使用できます。取得しているテーブルをハッシュキーで参照できますが、他のテーブル(外部クエリ内)には、そのarel_table
を使用できます。 。これを見る:
parents = Parent.arel_table
Parent.where(
Child.where(other_parent_id: nil, parent_id: parents[:id]).exists.not
)
文字列に少し頼り、Railsのwhere
へのパラメーターとしてサブクエリをフィードできるという事実に依存することで、Arelの使用量を減らすこともできます。 。あまり使用されませんが、Arelのメソッドを深く掘り下げる必要はないので、そのトリックまたはサブクエリを受け取る他のSQL演算子を使用できます(他に何かありますか?):
parents = Parent.arel_table
Parent.where('NOT EXISTS (?)',
Child.where(parent_id: parents[:id], other_parent_id: nil)
)
ここでの2つの主なポイントは次のとおりです。
- Arelで外部クエリのテーブルを参照して、通常のクエリを作成するのと同じ方法でサブクエリを作成できます。それは実際のテーブルではないかもしれません、それはエイリアスかもしれません!クレイジーなもの。
- Railsの
where
のパラメーターとしてサブクエリを使用できます 方法は問題ありません。