Korzystanie z arel
może cię daleko zaprowadzić. Trudną częścią jest to, jak nie pisać całego zapytania za pomocą arel
własna składnia zapytania?
Oto sztuczka:podczas tworzenia zapytania za pomocą where
, jeśli używasz arel
warunki, dodatkowe metody otrzymasz za darmo. Na przykład możesz śledzić podzapytanie, które tam masz, za pomocą .exists.not
, co da Ci (NOT ( EXISTS (subquery)))
Wrzuć to do where
rodzica -klauzula i gotowe.
Pytanie brzmi, jak odwołujesz się do zaangażowanych tabel? Potrzebujesz do tego Arela. możesz użyj where
Arela z jego brzydkimi warunkami, takimi jak a.eq b
. Ale dlaczego? Ponieważ jest to warunek równości, możesz zamiast tego użyć warunków Rails! Możesz odwołać się do tabeli, której dotyczy zapytanie, za pomocą klucza mieszającego, ale dla innej tabeli (w zapytaniu zewnętrznym) możesz użyć jej arel_table
. Obejrzyj to:
parents = Parent.arel_table
Parent.where(
Child.where(other_parent_id: nil, parent_id: parents[:id]).exists.not
)
Możesz nawet zredukować użycie Arela, odwołując się trochę do łańcuchów i opierając się na fakcie, że możesz przesyłać podzapytania jako parametry do where
Railsów . Nie ma z tego wiele pożytku, ale nie zmusza cię do zbytniego zagłębiania się w metody Arela, więc możesz użyć tej sztuczki lub innych operatorów SQL, które pobierają podzapytanie (czy są jeszcze jakieś inne?):
parents = Parent.arel_table
Parent.where('NOT EXISTS (?)',
Child.where(parent_id: parents[:id], other_parent_id: nil)
)
Oto dwa główne punkty:
- Możesz budować podzapytania w taki sam sposób, w jaki przywykłeś do budowania zwykłych zapytań, odwołując się do tabeli zewnętrznego zapytania za pomocą Arel. Może to nawet nie być prawdziwy stół, może to być pseudonim! Szalone rzeczy.
- Możesz użyć podzapytań jako parametrów dla
where
Railsów metoda dobrze.