在我的代码中,我有一个选项包括:
nodes_list =
Foo
.where(id: foo_ids)
.includes(node: [:nodes, node_image, :parent_node])
.includes(:bar, :foo_image)
.flat_map {|foo| [foo.node, foo.node.parent_node]}.uniq.compact
此部分工作正常,可以按预期避免N + 1个查询。但是,稍后在我的代码中,我有这个:
nodes_list.map do |node|
if node.nodes.empty?
image = node.foo.foo_image
else
image = node.node_image
end
{
id: node.id,
name: node.name,
image: image,
parent_id: node.parent_node,
}
end
在这种情况下,我在parent_node
,nodes
和node_image
上有N + 1个查询,这些查询应该在我的includes
中。如何避免那些N + 1查询?
答案 0 :(得分:3)
我认为您看到这些N + 1
查询的原因是您没有在parent_node
中包含任何内容我认为如果您这样写它可以避免:
nodes_list =
Foo
.where(id: foo_ids)
.includes(node: [:nodes, :node_image, parent_node: [:nodes, :node_image, :parent_node]])
.includes(:bar, :foo_image)
.flat_map {|foo| [foo.node, foo.node.parent_node]}.uniq.compact
完全独立于我想添加以下内容的问题:
您可以删除includes(:bar, :foo_image)
,因为这只会导致额外的工作。您使用foos
和bar
获取和装饰的foo_image
将被丢弃,而不使用这些预取的装饰。