Как найти отчеты для всех связанных серверов: company_id равен 5?
Это можно сделать, сначала найдя набор отчетов, в котором хотя бы один сервер имеет company_id = 5. Затем просто найдите отчеты, которыеНЕ в этом наборе.
server_conditions = Server.where.not(company_id: 5)
.or(Server.where(id: nil)) # Include reports which have NO servers.
reports_to_exclude = Report
.left_joins(:servers) # see notes about joins vs left_joins
.merge(server_conditions)
Report.where.not(id: reports_to_exclude) # ActiveRecord automatically selects `id` from reports_to_exclude, but it could be done explicitly, id: reports_to_exclude.select(:id)
объединения против left_joins
Если есть записи отчетов, которые НЕ имеют записей о связанных серверах, то joins
даст результат, отличный от left_joins
.left_joins
будет исключать таких отчетов, в то время как joins
будет включать их.
Вам решать, какое поведение является правильным.Если вы знаете, что у вас никогда не будет отчета, у которого нет связанного сервера, то в любом случае сработает (возможно, лучше использовать joins
, но вам всегда следует обращать внимание на влияние на производительность базы данных).
findв отчетах со всех соответствующих серверов company_id не равен 5?
Принцип здесь тот же.Во-первых, найдите набор отчетов, в котором есть сервер с company_id, равным 5. Затем выберите все остальные отчеты, которых нет в этом наборе.
reports_to_exclude = Report.joins(:servers).where(servers: { company_id: 5 })
Report.where.not(id: reports_to_exclude)
Можно ли использовать, используя только где?
Это как можно ближе к вам.