2015-04-24 2 views
1

У меня есть представление, которое отображает записи как от родителя (в моем случае), так и от его детей (строки в моем случае), и хотя это работает, я чувствую, что я не делая это правильным способом Rails MVC.Rails Parent Child Model View Best Practice

Мои модели:

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> 

Мой метод печати возвращает все группы, которые прекрасно точно так же, как индексный метод. Он генерирует следующий 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).

Как я мог сделать это лучше?

Заранее спасибо

ответ

4

Вы должны делать то, что называется eager loading (в отличие от отложенной загрузки), вам необходимо проинструктировать рельсы для запроса всех детей заранее, вместо выборки каждого ребенка в петле, это можно легко сделать с помощью метода includes

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

Таким образом, вы получите только 2 запросов (один для групп и одна для линий) и никаких запросов при рендеринге мнения

+0

Спасибо. Я, конечно, не знал об этом. Нужно ли мне вообще менять свой вид, поскольку он все еще, кажется, выполняет запросы линии? – comphelp

+0

Я нашел свою проблему. Я добавил порядок в представлении (после публикации), и это вызвало несколько запросов. Когда я перемещаю заказ на контроллер (в сочетании с вашими инструкциями), он работает отлично. ура – comphelp