在rails中迭代嵌套对象的最佳方法是什么

rav*_*rav 3 ruby ruby-on-rails

嗨,我想问哪一个更好,如果两个都不是一个好方法,那么迭代嵌套模型的最佳方法是什么.

方法#1.

@categories = Category.all

@categories.each do |category|
   category.sub_categories.each do |sub_category|
     puts sub_category.name
   end
end
Run Code Online (Sandbox Code Playgroud)

假设我有100个类别,每个类别包含100个子类别,因此该appraoch将生成100x100个查询

方法#2.

@categories = Category.all
@sub_categories = SubCategory.all

@categories.each do |category|
    @sub_categories.each do |sub_category|
        if category.id == sub_category.category_id
          puts sub_category.name
        end
    end
end
Run Code Online (Sandbox Code Playgroud)

将只有2个查询但将迭代"@sub_categories"100次.

我想知道哪一个更好?

Car*_*rew 5

第一个肯定更好,特别是因为你可以利用Rails的急切加载来减少查询.

这是我要做的:

#controller  
@categories = Category.includes(:sub_categories)

#view, haml-style  
%ul
  - @categories.each do |category|
    %li
      %h2= category.name
      %ul
        - category.sub_category.each do |sub_category|
          %li= sub_category.name
Run Code Online (Sandbox Code Playgroud)

为什么这样更好?

  1. 使用Rails急切加载减少查询:上面的控制器行最多将运行2个查询
  2. 更简单,更清晰的代码
  3. 你在视图/输出中避免使用复杂的,不必要的代码来检查匹配category.id == sub_category.category_id.

关于第二个例子的进一步说明

假设你有10个类别,每个包含10个子类别,总共100个.第一个例子将进行10次@category迭代,每次迭代10次includes(:sub_categories),对于(这是模糊数学)110"数组迭代"总计.

第二个例子将进行10次@category迭代,每次迭代100次@sub_categories,对于(模糊数学再次)1010"数组迭代"总计.这肯定更糟.