0

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?

1
  • I think you might find more if you look up "active record relation(ships)" Commented May 3, 2015 at 13:16

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

Comments

0

This should be a lot simpler,

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

But to make it even cheaper in terms of queries, just do something like this

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

Then in the views ( just basic idea )

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

This way ActiveRecord will only hit the database twice, once for groups and once for microposts.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.