Попытка выбрать все объекты, где хотя бы один связанный объект не соответствует запросу - PullRequest
0 голосов
/ 24 мая 2019

У меня есть две связанные модели. Product имеет множество DescriptorFiles, а DescriptorFile имеет логический атрибут approved.

Я хочу найти все продукты, для которых ни один из связанных файлов дескриптора не одобрен.

То есть: я хочу найти все товары, где ВСЕ descriptor_files approved: false.

Я только что нашел решение, но я бы предпочел сделать все это с помощью активных запросов записей:

Product.all - Product.joins(:descriptor_files).where(descriptor_files: {approved: true})

Это работает, но, как уже говорилось, было бы здорово, если бы я мог вернуть объект активной записи.

Спасибо!

Ответы [ 3 ]

1 голос
/ 24 мая 2019

Вы можете оставить файлы дескриптора LEFT JOIN, которые одобрены, и убедиться, что вы извлекаете только те записи, в которых ничего не объединено .(Это также будет запрашивать Продукты без файлов дескрипторов).

Product.joins('LEFT OUTER JOIN descriptor_files ON descriptor_files.product_id = product.id AND descriptor_files.approved = true')
       .where(descriptor_files: { id: nil })

К сожалению, соединение должно быть написано вручную, хотя вы можете использовать Arel для генерации предложения Join.

1 голос
/ 24 мая 2019

В рельсах 5+ вы можете использовать where.not Так что в этом случае ваш запрос будет

Product.where.not(id: 
  Product.select(:id).joins(:descriptor_files)
      .where(descriptor_files: {approved: true})
) 

Это будет использовать подзапрос вашей исходной версии в качестве предложения NOT IN. Результирующий SQL

SELECT 
  products.* 
FROM 
  products
WHERE 
  products.id NOT IN ( 
    SELECT 
      products.id
    FROM 
      products
      INNER JOIN descriptors ON descriptors.product_id = products.id
    WHERE 
      descriptors.approved = true
  )
0 голосов
/ 24 мая 2019

В качестве альтернативы, вы можете использовать left_outer_joins для рельсов 5 +

results = Product.left_outer_joins(:descriptor_files)
                      .where(descriptor_files: {approved: false})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...