Ruby on Rails & Active Record - поиск всех x, которые не появляются в данном y - PullRequest
4 голосов
/ 09 мая 2011

Допустим, у меня есть 2 модели Album и Image и модель соединения с именем AlbumImage (и 3 соответствующие таблицы в базе данных).

Модели имеют общие свойстваАссоциация-ко-многим - Album имеет множество от images до album_images и наоборот.

TL; dr версия

Как найти каждое изображение, которое не отображаетсяданный альбом?

Длинная версия

Я ищу что-то эквивалентное следующему SQL:

SELECT * FROM images
WHERE NOT EXISTS (
    SELECT * FROM album_images
    WHERE album_images.image_id = images.id
    AND album_images.album_id = ?
);

т.е. выберите каждое изображение, где не существует строкив таблице album_images с тем же идентификатором изображения и идентификатором данного альбома.

Но я, к сожалению, не знаю, как выразить это в синтаксисе запроса Rails.

1 Ответ

4 голосов
/ 09 мая 2011

Попробуйте:

Опция 1

Image.all(:conditions => ["images.id NOT IN ( 
  SELECT a.image_id FROM album_images a WHERE a.album_id = ?)", alb_id])

Этот подход лучше, чем использование NOT EXISTS, так как результат подзапроса здесь кэшируется БД.

Опция 2

Использование ВЛЕВОГО НАРУЖНОГО СОЕДИНЕНИЯ.

Image.all(:joins => "LEFT OUTER JOIN album_images a 
    ON a.album_id = #{alb_id} AND a.image_id = images.id",
 :conditions => "a.image_id IS NULL")

Опция 3

Есликоличество изображений в альбоме ограничено, и вы не возражаете понести стоимость одного дополнительного запроса:

conditions = ["id NOT IN (?)", 
  @album.album_images.map(&:image_id)] unless @album.album_images.empty?

Image.all(:conditions => conditions)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...