Возвращать только ассоциативные записи, которые включают все идентификаторы в массиве - PullRequest
0 голосов
/ 08 декабря 2018

Скажите, у меня есть следующие таблицы и отношения:

class Book has_many :book_genres end

class Genre has_many :book_genres end

class BookGenre belongs_to :book belongs_to :genre end

Если бы я хотел тольконайдите книги, которые имеют два конкретных идентификатора жанра (13005 и 9190),

Я думал, что мог бы сделать что-то вроде:

Book.where(book_genres: {genre_id: [13005, 9190]})

Но возвращаются книги, которыеимеют либо Жанры ID 13005, либо 9190.

Я также подумал, что, возможно, я мог бы отфильтровать его, выполнив что-то вроде:

Book.where(book_genres: {genre_id: [13005]}).where(book_genres: {genre_id: [9190]})

Но это тоже не работает.

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

Примечания:

Из этого сообщения (https://stackoverflow.com/a/3416838/1778314), Я пытался сделать это:

Book.joins(:book_genres).where(book_genres: { genre_id: [13005,9190]}).group("books.id").having("count(book_genres.id) = #{[13005, 9190].count}")

Но это тоже не работает (возвращает оба набора).

Кроме того, есть аналогичная публикация с использованием рецептов и ингредиентов без рабочего решения: Ruby On Rails 5, запрос activerecord, где идентификаторы ассоциации моделей включают ВСЕ идентификаторы в массиве

Ответы [ 3 ]

0 голосов
/ 08 декабря 2018

Я знаю, что следующее не является хорошим способом, но может решить вашу проблему,

Book.includes(:book_genres).select { |book| book.book_genres.map(&:genre_id).uniq.sort == [9190, 13005] }

Выше будет возвращаться вывод в типе Array вместо ActiveRecord::Relation, но он будет работать согласно вашему требованию.

0 голосов
/ 09 декабря 2018

Это сработало для меня:

Book.joins(:book_genres).where(book_genres: { genre_id: [13005, 205580]}).group("books.id").having('count(books.id) >= ?', [13005, 205580].size)

0 голосов
/ 08 декабря 2018

Книги, имеющие два идентификатора жанра (13005 и 9190),

book_ids_either_have_two_ids = Book. includes(:book_genres).where("book_genres.id IN ?= [3005 9190]")distinct.pluck(:id)

Book.where.not("id IN ?", book_ids_either_have_two_ids)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...