Rails 视图中的嵌套资源

Nested Resources in Rails views

我知道有很多关于 Rails 嵌套资源的文章,我浏览了很多,但都没有回答我的问题。

我有3个模型:用户、群组和微博。用户订阅群,每个群都有若干条微博。所有协会都已到位并且工作正常。

我想要实现的是让主页上的用户有他们小组的标签,每个标签都列出了该小组内的微博。

这就是我现在正在做的事情:

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

我在用户模型中创建了一个功能,returns属于特定组的微博

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 中的每个组下吗?

我认为您的视图工作方式很正常,但我怀疑您在数据库中使用关系的方式至少不是 railsy。

我假设您正在使用 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

但这有点乏味。

这个应该简单很多,

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 只会访问数据库两次,一次用于群组,一次用于微博。