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 只会访问数据库两次,一次用于群组,一次用于微博。
我知道有很多关于 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 只会访问数据库两次,一次用于群组,一次用于微博。