我有三个相互链接的对象。它看起来像这样:
tree[
id: 1,
name: "name"
]
branch[
id: 1,
tree_id: 1
]
leaf[
id: 1,
branch_id:1
]
我需要知道每棵树有多少叶子,所以我创建了一个嵌套的for循环:
更新
我更新了代码:
results = []
trees = Tree.all
trees.each do |tree|
branches = Branch.where(tree_id: tree.id)
branches.each do |branch|
leaves_count = leaves.where(branch_id: branch.id).count
end
results.push( {
tree: tree.name,
leaves: leaves_count
})
end
使用此代码我收到一组对象:
results = [{
tree: "oak",
leaves: 4
}, {
tree: "redwood",
leaves: 6
}]
我想要相同的输出,但是以轨道方式
这有效,但感觉真的很笨重。有没有人知道修复此问题的方法?
更新已解决
Yury Lebedev的答案是正确的,但通过他之前的回答,我发现了另一种方式。所以这有效(尤里的答案):Tree.find_each do |tree|
Branch.where(tree_id: tree.id).joins(:leaves).count('leaves.id')
end
这也有效:
Tree.find_each do |tree|
Tree.joins(branches: :leaves).where(id: tree.id).count('leaves.id')
end
作为一个延续问题(不确定我是否应该在回答的问题上这样做?)我想知道我有一个比另一个更好/更快,或者他们是否相同。< / p>
答案 0 :(得分:2)
您可以尝试使用连接查询(这只会对数据库进行一次查询):
Leaf.joins('inner join branches on leaves.branch_id = branches.id')
.group('branches.tree_id').count
这将为您提供一个以tree_id
为键的哈希值,并将计数保留为值。
如果你想遍历树,并获得每个树的叶数,你可以这样做(如果你有n棵树,这将对数据库进行n次查询):
trees.each do |tree|
leaves_count = Branch.where(tree_id: tree.id).joins('inner join leaves on leaves.branch_id = branches.id')
.count('leaves.id')
end
如果您的模型中有关联,那么这可以更容易地完成:
class Three < ActiveRecord::Base
has_many :branches
has_many :trees, through: :branches
end
class Branch < ActiveRecord::Base
belongs_to :tree
has_many :leaves
end
class Leaf < ActiveRecord::Base
belongs_to :branch
delegate :tree, to: :branch
end
然后是一个查询:
Leaf.joins(:branch).group('branches.tree_id').count
And for a query for each tree:
Tree.find_each do |tree|
Branch.where(tree_id: tree.id).joins(:leaves).count('leaves.id')
end