Rails 5: запрос, который исключает результаты, если они связаны с определенной записью - PullRequest
0 голосов
/ 15 января 2019

У меня есть две модели: Playlist и Item. Я хочу создать запрос, который возвращает все плейлисты, кроме тех, которые имеют определенный элемент.

Это модели:

class Playlist < ApplicationRecord
  has_many :items
end

class Item < ApplicationRecord
  belongs_to :playlist
end

Это запрос, который не работает, так как могут быть плейлисты, которые имеют указанный элемент, но также и несколько других, и, если у них есть другие элементы, они включаются (что я не хочу):

Playlist.left_outer_joins(:items).where.not(items: { uid: id })

Для справки, моя СУБД - PostgreSQL 9,6

Ответы [ 2 ]

0 голосов
/ 15 января 2019

У меня нет настройки для быстрого тестирования, но я думаю, что вы можете использовать подзапрос Rails ActiveRecord:

Playlist.where.not(id: Item.select(:pl_id).where(id: id_to_exclude))

Здесь pl_id - это имя атрибута в Item, соответствующего идентификатору списка воспроизведения. Я также предполагаю, что id является первичным ключом в каждой из ваших таблиц. Это может быть компактным способом для результата, но не самым эффективным с точки зрения запроса.

0 голосов
/ 15 января 2019

Возможно, это можно написать лучше, но это должно сработать:

join_sql = Arel.sql(
  "LEFT OUTER JOIN items ON " \
  "(items.playlist_id = playlists.uid " \
  "AND items.some_id = '#{item.some_id}')"
)

Playlist.where(owner: owner)
        .joins(join_sql)
        .where(items: { playlist_id: nil })

Концепция похожа на эту: https://stackoverflow.com/a/2686266

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...