I know there are many articles on Rails nested resources and I went through a lot of them but nothing answers my question.
I have 3 models: user, group and micropost. User subscribes to groups, each having a number of microposts. All the association are in place and working fine.
What I want to achieve is to have the homepage where users have tabs of their groups, each listing the microposts within that group.
This is what I am doing at the moment:
#Home Controller
def home
if logged_in?
@groups=current_user.group
end
end
I have created a function in the user model that returns microposts belonging to a specific group
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
In my view
<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>
This is working fine at the moment, but I suspect it is the right way to do it. I would like to be able to pass resources from the controller to the view rather than calling the model action from the view.
Is there any way to define @microposts in the controller and having it nested under each group in @groups?
I think the way your view works is quite normal, but I suspect that the way you are using relationships in the database is non railsy at the least.
I assume you are using ActiveRecord.
Inside your models you should have something like this.
# 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
Thus in your controller you could set @groups = current_user.groups
and in your view you could call group.microposts.each
.
If you wanted to set both in the controller you could do something like this:
@groups = current_user.groups
@microposts = @groups.map(&:microposts)
And then in your view you could call:
@groups.each_with_index do |group, index|
# do something with group
@microposts[index].each do |micropost|
# do something with micropost
end
end
But this is kind of tedius.