Как избежать проблем с загрузкой в ​​рельсах 4 - PullRequest
0 голосов
/ 22 ноября 2018

Вот мой код ниже,

У клиента есть много событий с внешним ключом client_id в таблице 'events'

has_many :events

В консоли

clients = Client.where(id: [110,112,113,115]).includes(:events)
=>  Client Load (0.4ms)  SELECT `clients`.* FROM `clients` WHERE `clients`.`id` IN (110, 112, 113, 115)
    Event Load (0.5ms)  SELECT `events`.* FROM `events` WHERE `events`.`client_id` IN (110, 112, 113, 115)

Но при следующем запуске

clients.each { |cr| cr.events.count }
   (0.4ms)  SELECT COUNT(*) FROM `events` WHERE `events`.`client_id` = 110
   (0.3ms)  SELECT COUNT(*) FROM `events` WHERE `events`.`client_id` = 112
   (0.3ms)  SELECT COUNT(*) FROM `events` WHERE `events`.`client_id` = 113
   (0.3ms)  SELECT COUNT(*) FROM `events` WHERE `events`.`client_id` = 115

Я получаю N + 1 запросов, я что-то упускаю.Пожалуйста, помогите

Обновление:

Из ответа при условии, что я получил подсказку, я хотел идентификаторы событий, поэтому я пытался, как,

clients.each { |cr| cr.events.ids }
clients.each { |cr| cr.events.pluck(:id) }

ТакN + 1 запрос был запущен, затем я работал со следующими и решил,

clients.each { |cr| cr.events.map(&:id) }

Я рассматривал Relation как массив и использовал map вместо ids или pluck и решал, нет N +1 запрос был уволен.

Ответы [ 2 ]

0 голосов
/ 22 ноября 2018

Если ваша цель - получить идентификаторы событий, используйте join with pluck

event_ids = Client.where(id: [110,112,113,115]).joins(:events).pluck('events.id')
0 голосов
/ 22 ноября 2018

.count в случае ActiveRecord Relation просто запустит запрос.Если вы измените его на .size, будет проверена длина массива загруженных элементов, что вам и нужно.

...