如何避免Rails中的预载问题4

时间:2018-11-22 08:19:16

标签: ruby-on-rails ruby-on-rails-4 activerecord

下面是我的代码,

客户在“事件”表中有许多带有外键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) } 而不是mapids并解决了,没有N + 1查询被触发。

2 个答案:

答案 0 :(得分:2)

如果您的目标是获取事件ID,请使用pluck连接

event_ids = Client.where(id: [110,112,113,115]).joins(:events).pluck('events.id')

答案 1 :(得分:1)

.count对于ActiveRecord Relation将仅运行查询。如果将其更改为.size,将检查要加载的项目的数组长度,这就是您要执行的操作。