Как я могу получить записи с точным has_many через количество записей на рельсах - PullRequest
0 голосов
/ 19 декабря 2018

У меня есть отношения многие ко многим через has_many через

class Person < ActiveRecord::Base
  has_many :rentals
  has_many :books, through rentals
end

class Rentals < ActiveRecord::Base
  belongs_to :book
  belongs_to :person
end

class Book < ActiveRecord::Base
  has_many :rentals
  has_many :persons, through rentals
end

Как я могу получить людей, у которых есть только одна книга?

Ответы [ 2 ]

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

Если таблица для Person называется persons, вы можете создать соответствующий SQL-запрос, используя DSL-запрос ActiveRecord:

people_with_book_ids = Person.joins(:books)
                             .select('persons.id')
                             .group('persons.id')
                             .having('COUNT(books.id) = 1')
Person.where(id: people_with_book_ids)

Хотя это две строки кода Rails, ActiveRecord объединит его водин вызов в базу данных.Если вы запустите его в консоли Rails, вы можете увидеть инструкцию SQL, которая выглядит примерно так:

SELECT "persons".* FROM "persons" WHERE "deals"."id" IN 
(SELECT persons.id FROM "persons" INNER JOIN "rentals" 
ON "rentals"."person_id" = "persons"."id"
INNER JOIN "books" ON "rentals"."book_id" = "books"."id" 
GROUP BY persons.id HAVING count(books.id) > 1)
0 голосов
/ 19 декабря 2018

Если это то, что вы хотите делать часто, Rails предлагает так называемый кеш счетчика :

Опция: counter_cache может быть использована для поиска числаболее эффективные принадлежащие объекты.

С помощью этого объявления Rails будет поддерживать значение кэша в актуальном состоянии, а затем возвращать это значение в ответ на метод size.

По сути, это помещаетновый атрибут на вашем Person с именем books_count, который позволит вам довольно просто фильтровать по количеству связанных книг:

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