0

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
messanjah
  • 8,977
  • 4
  • 27
  • 40
Jonathan
  • 673
  • 1
  • 10
  • 32

3 Answers3

1

Have to do it as answer:

In your Category model:

def to_param
  name
end

But please accept Logan's anwer as the correct one, because he solves your original problem.

Klaus
  • 1,591
  • 1
  • 12
  • 18
0

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 
Logan Serman
  • 29,447
  • 27
  • 102
  • 141
  • Thanks Logan for the detailed answer! How would I go about linking to the category in my index view? Also is there anyway to change the URL to be the name attribute instead of the id? – Jonathan Mar 28 '15 at 16:30
  • Run `rake routes` to see your possible routes. With Logans explanation you will have categories_post_path which will lead you to a specific category. You can use to_param to make the name of the category to a parameter. – Klaus Mar 28 '15 at 16:36
  • Thanks Klausinho - appreciated! – Jonathan Mar 28 '15 at 16:38
  • @klausinho How would I go about doing the to_param? – Jonathan Mar 28 '15 at 16:44
  • @klausinho Currently getting **undefined local variable or method `categories_post_path'** from putting **<%= link_to category.name, categories_post_path %>** – Jonathan Mar 28 '15 at 16:47
  • I mentioned the correct path helper in my post, `category_posts_path()`. `categories_post_path` is incorrect. – Logan Serman Mar 28 '15 at 19:11
0
def index 
 if params[:category_id]
  @posts = Post.where("category_id = ?", params[:category_id])
 else
   @posts = Post.all
 end 
end

An alternative to Logan's Answer as in some cases it might not work.

Aditya Joardar
  • 580
  • 5
  • 11