Rails Parent Child 模型视图最佳实践

Rails Parent Child Model View Best Practice

我有一个视图显示 parent(在我的例子中是组)和 children(在我的例子中是行)的记录,虽然它有效,但我觉得我我没有按照正确的 Rails MVC 方式进行操作。

我的模型是:

class Group < ActiveRecord::Base
  has_many :lines, dependent: :destroy
  belongs_to :user
end

class Line < ActiveRecord::Base
  belongs_to :group
end

我的群组控制器打印方法是:

def print
  @groups = current_user.groups.order('position ASC').all
end

我的打印视图是:

<table class="table table-striped">
  <thead>
    <tr>
      <th>Description:</th>
    </tr>
  </thead>
  <tbody>
    <% @groups.each do |group| %>
      <tr>
        <td><h3><%= group.description %></h3></td>
      </tr>
      <% group.lines.each do |line| %>
        <tr>
          <td><%= line.description %></td>
        </tr>
      <% end %>
    <% end %>
  </tbody>
</table>

我的打印方法returns所有组,就像索引方法一样好。它生成以下 SQL:

SELECT "groups".* FROM "groups"  WHERE "groups"."user_id" = ?  ORDER BY position ASC  [["user_id", 1]]

我认为我出错的地方是我在上面的打印视图中得到了这段代码:

lines group.lines.each do |line|

每次为每个组运行时,它都会生成另一个这样的查询(对于 each 组:

SELECT "lines".* FROM "lines"  WHERE "lines"."group_id" = ?  [["group_id", 667]

这似乎效率低下,因为查询 运行 很多次。我还觉得我的查询实际上应该是来自我的控制器的 运行 而不是我的视图(即正确的 Rails / MVC 方式)。

我怎样才能做得更好?

提前致谢

你需要做所谓的eager loading(与延迟加载相反),你需要指示rails提前查询所有children,而不是获取循环中的每个 child,这可以使用 includes 方法

轻松完成
def print
  @groups = current_user.groups.includes(:lines).order(position: :asc)
end

这样你只会得到 2 个查询(一个用于组,一个用于行)并且在呈现视图时没有查询