Използване на arel може да те отведе доста далеч. Сложната част е как да не напишете цялата си заявка с arel собствен синтаксис на заявката?
Ето един трик:когато създавате вашата заявка, като използвате where , ако използвате arel условия, получавате някои допълнителни методи безплатно. Например, можете да опашкате подзаявката, която имате там, с .exists.not , което ще ви даде (NOT ( EXISTS (subquery))) Хвърлете това в where на родителя -клауза и сте готови.
Въпросът е как препращате към включените таблици? Имаш нужда от Арел за това. Вие можете използвайте where на Arel със своите грозни условия като a.eq b . Но защо? Тъй като това е условие за равенство, можете да използвате условията на Rails вместо това! Можете да посочите таблицата, която заявявате, с ключ за хеширане, но за другата таблица (във външната заявка) можете да използвате нейния arel_table . Гледайте това:
parents = Parent.arel_table
Parent.where(
Child.where(other_parent_id: nil, parent_id: parents[:id]).exists.not
)
Можете дори да намалите използването на Arel, като прибягвате малко до низове и разчитате на факта, че можете да подавате подзаявки като параметри към where на Rails . Няма много полза от него, но не ви принуждава да се задълбочавате твърде много в методите на Arel, така че можете да използвате този трик или други SQL оператори, които приемат подзаявка (има ли други?):
parents = Parent.arel_table
Parent.where('NOT EXISTS (?)',
Child.where(parent_id: parents[:id], other_parent_id: nil)
)
Двете основни точки тук са:
- Можете да създавате подзаявки точно по същия начин, по който сте свикнали да създавате обикновени заявки, препращайки към таблицата на външната заявка с Arel. Може дори да не е истинска маса, може да е псевдоним! Луди неща.
- Можете да използвате подзаявки като параметри за
whereна Rails методът е много добър.