Стремительная ассоциация загрузки при запросе данных ассоциации - PullRequest
1 голос
/ 16 апреля 2019

У меня есть модель "Пользователь", которая имеет отношение один ко многим с другой моделью "Членство".Членство имеет поле с именем «группа», которая имеет название группы.Я хочу запросить все записи пользователя, которые находятся в определенной «группе», и хочу загрузить все «членства» для каждого возвращенного пользователя.

Прежде чем я продолжу, я знаю, что обычно вы реализуете «группу»"смоделируйте и сделайте членство объединяющей таблицей между пользователем и группой и просто запросите конкретную группу для всех ее пользователей.Этот пример немного надуманный, но он представляет реальный случай, над которым я работаю.

В любом случае, я попытался выполнить следующий запрос:

User.includes(:memberships).where(memberships: { group: groupname })

Однако, пока он возвращает правильных пользователей, он только стремится загрузить членство, которое соответствует запросу.Иными словами, если пользователь «Боб» находится в «красной» и «синей» группах и я запрашиваю всех пользователей «синей» группы, пользователь «Боб» возвращается среди результатов, но только его «синий»загружено членство в группе.

Есть ли способ сделать это с помощью одного запроса к БД И стремиться загрузить все членства каждого возвращенного пользователя?

1 Ответ

2 голосов
/ 16 апреля 2019

В вашем примере выполняется один запрос к БД, поскольку в ассоциации существует условие запроса.Обычно includes выполняет два запроса к БД, один для загрузки пользователей, а другой для загрузки связанных членств.

Я обратил на это внимание, поскольку существует решение, которое работает при выполнении двух запросов к БД, и этоотлично (по умолчанию активная загрузка ActiveRecord)

User.preload(:memberships).joins(:memberships).where(memberships: {group: groupname})

Примечание: в этом примере вместо includes используется метод preload.Это означает, что условия запроса для связанной таблицы должны применяться только в первом запросе и не влиять на второй запрос, который предварительно загружает memberships.По умолчанию, когда в связанной таблице нет дополнительных условий запроса, include работает как preload.

Первый запрос извлекает всех пользователей, имеющих членство в требуемой группе.

Второй запросполучит все связанные членства без каких-либо дополнительных условий.

...