Search code examples
ruby-on-railsrubyruby-on-rails-4has-and-belongs-to-many

Display all posts from a certain category


I'm looking to display all posts from a certain category on a page, I currently have Posts & Category models linked by a HABTM relationship. I want to be able to click the link on my index.html.erb and go through to a page that lists all the posts which belong to that certain category.

Do I need to create a controller for category and new routes?

Post.rb

class Post < ActiveRecord::Base
  has_and_belongs_to_many :categories
  belongs_to :user
end

Category.rb

class Category < ActiveRecord::Base
  has_and_belongs_to_many :posts
end

Index.html.erb (My current way to display the category for each post)

<% post.categories.each do |category| %>
  <% category.posts.each do |post| %>
    <%= link_to category.name, post_url(post) %>
  <% end %>
<% end %>

** Update **

After Answer routes have been produced as below.

          category_posts GET    /categories/:category_id/posts(.:format)          posts#index
                     POST   /categories/:category_id/posts(.:format)          posts#create
   new_category_post GET    /categories/:category_id/posts/new(.:format)      posts#new
  edit_category_post GET    /categories/:category_id/posts/:id/edit(.:format) posts#edit
       category_post GET    /categories/:category_id/posts/:id(.:format)      posts#show
                     PATCH  /categories/:category_id/posts/:id(.:format)      posts#update
                     PUT    /categories/:category_id/posts/:id(.:format)      posts#update
                     DELETE /categories/:category_id/posts/:id(.:format)      posts#destroy
          categories GET    /categories(.:format)                             categories#index
                     POST   /categories(.:format)                             categories#create
        new_category GET    /categories/new(.:format)                         categories#new
       edit_category GET    /categories/:id/edit(.:format)                    categories#edit
            category GET    /categories/:id(.:format)                         categories#show
                     PATCH  /categories/:id(.:format)                         categories#update
                     PUT    /categories/:id(.:format)                         categories#update
                     DELETE /categories/:id(.:format)                         categories#destroy

Solution

  • You can nest posts inside categories

    resources :categories do
      resources :posts
    end
    

    This will make routes like categories/1/posts and URL helpers like category_posts_path(1) where 1 is the category ID. Then in your posts controller, you will have params[:category_id] available which can lookup the category and then fetch the posts. Something like

    if params[:category_id]
      @category = Category.find params[:category_id]
      @posts = @category.posts
    else
      @posts = Post.all
    end