ruby-on-rails - 如何避免 Rails 4 中的 Eagerloading 问题
问题描述
下面是我的代码。
客户端在“事件”表中有许多带有外键 client_id 的事件
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 个查询,我遗漏了一些东西。
更新
从提供的答案中我得到了线索,我想要事件的 id,所以我正在尝试,
clients.each { |cr| cr.events.ids }
clients.each { |cr| cr.events.pluck(:id) }
所以 N+1 个查询被解雇了,然后我解决了以下问题,
clients.each { |cr| cr.events.map(&:id) }
我将 Relation 视为 Array 并使用map
orids
并pluck
解决了,没有 N+1 查询被触发。
解决方案
如果您的目标是获取事件 ID,请使用 join with pluck
event_ids = Client.where(id: [110,112,113,115]).joins(:events).pluck('events.id')
推荐阅读
- angular - RXJS 将 Observable 转换为布尔值
- python - 缺少 Python 3.4 venv bash 激活脚本
- r - 通过另一列中设置的参数计算两列数据的比率
- google-visualization - 根据mysql值改变谷歌饼图切片的颜色
- aframe - 更改 A 资产上的“src”不会更新材料
- r - 从 r shiny 的传单中控制 popupImage 的大小
- marklogic - 无法删除多个集合。
- google-chrome - 过滤 REST api 调用
- cmd - 从 Windows cmder 获取带有“调用”的 cmd 文件
- php - Preg Match Subpatterns - 如何匹配字符串后面的所有 TD