2015-05-03 2 views
0

Я знаю, что есть много статей о вложенных ресурсах Rails, и я прошел через многие из них, но ничто не отвечает на мой вопрос.Вложенные ресурсы в представлениях Rails

У меня есть 3 модели: пользователь, группа и микропоста. Пользователь подписывается на группы, каждый из которых имеет несколько микросообщений. Все ассоциации действуют и работают нормально.

Я хочу добиться того, чтобы на главной странице, где у пользователей есть вкладки своих групп, перечислены микропосты внутри этой группы.

Это то, что я делаю в данный момент:

#Home Controller 
def home 
if logged_in? 
    @groups=current_user.group 
end 
end 

Я создал функцию в модели пользователя, которая возвращает microposts, принадлежащие к определенной группе

def group_feed(group_id) 
    microposts_ids = "SELECT micropost_id from groupings WHERE group_id IN (#{group_id})" 
    Micropost.where("id IN (#{microposts_ids})") 
end 

На мой взгляд

<div class="panel-body"> 
    <div class="tab-content"> 
     <% @groups.each do |group| %> 

     <div class="tab-pane fade <%= 'in active' if current_user.group.first == group %>" id="<%=(group.name.gsub(/[0-9]+/, "")+group.id.to_s).parameterize%>"> 

     <div class="panel panel-default"> 

     <%= render current_user.group_feed(group.id) %> 

     </div> 

    </div> 
    <% end %> 
    </div> 
</div> 

В настоящий момент это работает нормально, но я подозреваю, что это правильный способ сделать это. Я хотел бы иметь возможность передавать ресурсы с контроллера на представление, а не вызывать действие модели из представления.

Есть ли способ определить @microposts в контроллере и установить его в каждой группе в @groups?

+0

Я думаю, вы можете найти больше, если будете искать «активное отношение к записи (суда)» – jphager2

ответ

1

Я думаю, что ваш взгляд работает вполне нормально, но я подозреваю, что способ использования отношений в базе данных не реже.

Предполагаю, что вы используете ActiveRecord.

Внутри моделей вы должны иметь что-то вроде этого.

# app/models/user.rb 
class User 
    has_many :groupings 
    has_many :groups, through: :groupings 
end 

# app/models/grouping.rb 
class Grouping 
    belongs_to :group 
    belongs_to :user 
end 

# app/models/group.rb 
class Group 
    has_many :microposts 
    # this would be optional 
    has_many :groupings 
    has_many :users, through: :groupings 
end 

# app/models/micropost.rb 
class Micropost 
    belongs_to :group 
end 

Таким образом, в вашем контроллере вы можете установить @groups = current_user.groups и на ваш взгляд, можно было бы назвать group.microposts.each.

Если вы хотите установить как в контроллер вы могли бы сделать что-то вроде этого:

@groups = current_user.groups 
@microposts = @groups.map(&:microposts) 

И тогда, на ваш взгляд можно было бы назвать:

@groups.each_with_index do |group, index| 
    # do something with group 
    @microposts[index].each do |micropost| 
    # do something with micropost 
    end 
end 

Но это своего рода tedius.

+0

большое спасибо.Я не был знаком с параметром each_with_index –

0

Это должно быть намного проще,

def group_feed(group_id) 
    Group.find(group_id).microposts 
end 

Но чтобы сделать его еще дешевле с точки зрения запросов, просто сделать что-то вроде этого

def home 
    if logged_in? 
    @groups = current_user.groups.includes(:microposts) 
    end 
end 

Тогда во взглядах (только основная идея)

@groups.each do |group| 
    #some html 
    group.microposts.each do |micropost| 
    render micropost 
    end 
end 

Таким образом, ActiveRecord будет обращаться к базе данных только дважды, один раз для групп и один раз для микроподов ц.