Один из вариантов - использовать ванильный SQL.
Если я правильно понимаю вашу схему, вам нужно что-то, что требует левых соединений больше, чем оператора ИЛИ.Оператор ИЛИ ВНУТРЕННЕГО СОЕДИНЕНИЯ не достигнет того, на что вы надеетесь, поскольку любая запись, у которой есть только крайний срок, но нет отчета, не будет возвращена.Вместо этого LEFT JOIN возвращает вам все записи учетных записей, в которых есть соответствующие идентификаторы user_id в таблицах сроков или отчетов.
select * from accounts
left join deadlines on deadlines.user = accounts.user
left join reports on reports.user = accounts.user
where day ...
and (reports.user IS NOT NULL or deadline.user IS NOT NULL)
В Rails 4 я полагаю, что вы можете указать код SQL для объединения, при этом объединяя в цепочкупункт, как вы бы обычно.Таким образом, это будет выглядеть так:
joinsql = "left join deadlines on
deadlines.user = accounts.user
left join reports
on reports.user = accounts.user"
Account.join(joinsql).where(
accounts: {user: user},
deadline: {day: (Date.today - 1.day..Date.today)}
).where("reports.user IS NOT NULL or deadlines.user IS NOT NULL")
После этого вы сможете получить доступ к результатам для всех соединенных таблиц.
Обратите внимание на добавление второго предложения where, связанного с первым, эффективно Иобычное текстовое условие, гарантирующее, что оба отчета и крайние сроки не являются пустыми.
Если у вас есть связи, соединяющие таблицы через атрибут user, то вы можете использовать простые запросы Active Record для использования
Account.includes(:accounts).includes(:deadlines).where...
См .: http://guides.rubyonrails.org/active_record_querying.html#specifying-conditions-on-eager-loaded-associations
Другой вариант, позволяющий избежать LEFT JOIN, - это использовать внутреннее соединение для одной таблицы и UNION с аналогичным запросом с внутренним соединением для другой таблицы.Чтобы это работало, вы должны указать возвращаемые поля с .select
, чтобы объединение могло работать.На мой взгляд, это более сложно.
В любом случае, зачастую проще просто написать SQL до точки условий условия where, которые содержат ввод пользователя, чем пытаться угадать, что собирается Railsсделать, чтобы создать запрос, который вы хотите.