Почему использование объединений и включение с find_each приводит к неправильному счетчику итераций - PullRequest
2 голосов
/ 18 октября 2019

У меня есть такое отношение

users = User.joins(:occupation).includes(:occupation)
count = 0
users.find_each do |u|
  count += 1
end
count

count не возвращает то же число, что и users.count

Кажется, всегда возвращается число меньше, чем я ожидаю. Если я запускаю этот код, я получаю правильное количество

count = 0
users.each do |u|
  count += 1
end
count

Это возвращает правильное число

Я смог изолировать проблему для моего пользователя с отношением занятия. Однако я не уверен, что является основной проблемой. Есть идеи, что может вызвать это?

1 Ответ

6 голосов
/ 18 октября 2019

Вам нужно учесть, что происходит в базе данных, чтобы получить ответ.

Делая users.joins(:occupation), вы запрашиваете пользователей, присоединившихся к профессии. Это будет внутреннее объединение , поэтому вы получите результаты только для пользователя, у которого есть профессия. По сути, вы запрашиваете количество всех пользователей, имеющих профессию.

Вы можете сделать users.left_outer_joins(:occupation), который выполнит внешнее соединение и вернет всех пользователей (присоединение). их на занятие, если у них есть занятие).

Если вы просто хотите достаточно эффективно загружать пользователей и связанные с ними занятия, вы можете использовать users.includes(:occupation), что исключает явное объединение их в один запрос (если вы не ссылаетесь на них). Поля заполнения в запросе, но это совсем другой вопрос, я подозреваю).

Обратите внимание, что вы можете получить похожую проблему подсчета сверх , если присоединитесь к ассоциации, которая имеет много значений. В этом случае вы получите несколько строк в результатах для каждой объединенной записи (например, пользователь с двумя профессиями будет учитываться дважды).

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