我有一个视图,显示父母(在我的情况下是小组)和它的孩子(在我的情况下是行)中的记录,虽然它有效,但我感觉我是没有采用正确的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>
我的print方法返回所有正常的组,就像索引方法一样。它生成以下SQL:
SELECT "groups".* FROM "groups" WHERE "groups"."user_id" = ? ORDER BY position ASC [["user_id", 1]]
我认为我出错的地方是我在上面的打印视图中获得了此代码:
lines group.lines.each do |line|
每次针对每个组运行时,它会生成另一个这样的查询(对于每个组:
SELECT "lines".* FROM "lines" WHERE "lines"."group_id" = ? [["group_id", 667]
由于查询运行很多次,这似乎效率低下。我也告诉我,我的查询实际上应该是从我的控制器运行而不是我的视图(即正确的Rails / MVC方式)。
我怎样才能做得更好?
提前致谢
答案 0 :(得分:4)
您需要执行所谓的eager loading(而不是延迟加载),您需要指示rails事先查询所有子项,而不是在循环中获取每个子项,这可以轻松完成使用includes
方法
def print
@groups = current_user.groups.includes(:lines).order(position: :asc)
end
通过这种方式,您只能获得2个查询(一个用于组,一个用于行),并且在呈现视图时无查询