2011-02-03 180 views
2

如果我有一个Foo类型的模型,有许多类型Bar的子记录,我希望能够显示Foo记录的列表并显示子栏的数量记录。所以我有类似的东西...如何避免与DataMapper聚合N + 1

@foos.each do |foo| 
    puts foo.name 
    puts foo.bars.count 
end 

我怎样才能避免N+1 problem我的聚合?换句话说,我不想为每一行查询一个新的SELECT COUNT(*)...。我可以简单地创建一个SQL视图并将其映射到一个新的模型,但有没有更简单的方法?

回答

1

DataMpper对于这些东西是反复无常的,所以我会给你几个选项来尝试可能取决于你的真实代码的样子。

  1. 只要将计数改为大小,即放入foo.bars.size即可。 DM的战略性急切加载有时可以使用这种方法。

  2. 在@ foos.each循环之前强制加载负载,并将计数更改为大小,例如,

    @foos = Foo.all(...) 
    @foos.bars.to_a 
    @foos.each do | foo | 
        puts foo.name 
        puts foo.bars.size 
    end 
    
  3. 问题你@ foos.each循环以foo ID和酒吧计数返回结构前的原始的SQL查询,由食品ID #map那些成散列,并让他们在循环中。 (我只是不得不求助于这种无意义的一两次,我建议在它之前用#1和2来摆弄一下。)