下面是我的代码,
客户在“事件”表中有许多带有外键client_id的事件
FactoryBot.define do
factory :template do
template_category { create(:template_category) }
end
end
在控制台中
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)
我收到了N + 1个查询,但缺少了一些内容。请帮助
更新:
从提供线索的答案开始,我想要事件的ID,所以我尝试这样做,
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) }
我将Relation作为数组对待,并使用clients.each { |cr| cr.events.map(&:id) }
而不是map
或ids
并解决了,没有N + 1查询被触发。
答案 0 :(得分:2)
如果您的目标是获取事件ID,请使用pluck连接
event_ids = Client.where(id: [110,112,113,115]).joins(:events).pluck('events.id')
答案 1 :(得分:1)
.count
对于ActiveRecord Relation将仅运行查询。如果将其更改为.size
,将检查要加载的项目的数组长度,这就是您要执行的操作。