sidharth singh
sidharth singh

Reputation: 409

Ruby on rails route to a custom method in the controller from the view

I have a controller name posts. In my /config/routes.rb, I have used this -

resources :posts

/app/controllers/posts_controller.rb:

class PostsController < ApplicationController
    def new
            @post = Post.new
    end

    def show
            @post = Post.find(params[:id])
    end

    def categoryshow
            @post = Post.find(params[:category])
    end

    def index
            @posts = Post.all
    end

    def create
            @post = Post.new(params[:post])
            if @post.save
                    flash.now[:success] = "Your Post Successful"
                    redirect_to @post
            else
                    render 'new'
            end
    end
end

I am new to rails and I often get confused with routes. I have another static_pages controller. In there is a home.html.erb file.

What I want to do is to call -

def categoryshow
            @post = Post.find(params[:category])
end

'categoryshow' method of posts controller from /app/views/static_pages/home.html.erb

How do I manage that? If I use 'posts_path', it goes to index action instead of categoryshow action.

#

I read through the link and tried a couple of things from there. Here is the problem that I am facing:

When I tried this in the config/routes.rb

resources :posts do

    collection do

          get 'categoryshow'

    end

end

This generates a 'categoryshow_posts_path'

In my view, I used this:

<ul class="users">

     <%= Post::CATEGORIES.each do |category| %>

<li>

     <%= link_to category,categoryshow_posts_path %>

</li>

<% end %>

</ul>

My posts controller has the following method:

def categoryshow

        @post = Post.find(params[:category])

end

In this case, I am getting the following error:

ActiveRecord::RecordNotFound in PostsController#categoryshow

Couldn't find Post without an ID


Secondly, I tried out using non resourceful routes as mentioned in that link you provided:

 match ':posts(/:categoryshow(/:category))'

In the view, I am using this:

Categories

 <ul class="users">

 <%= Post::CATEGORIES.each do |category| %>

 <li>

     <%= link_to category,"posts/#{category}" %>

 </li> 

<% end %>

</ul>

In this case, our non resourceful route will match only if no other existing resourceful route matches. However, i am seeing that show action is matched and I get this error message:

This is the show action:

def show

        @post = Post.find(params[:id])

end

ActiveRecord::RecordNotFound in PostsController#show

Couldn't find Post with id=Politics

Upvotes: 17

Views: 30711

Answers (1)

Dave Newton
Dave Newton

Reputation: 160170

Check out the "Adding More RESTful Actions" sections of the routing docs.

resources :posts do
  collection do
    get 'categoryshow'
  end
end

Or:

resources :posts do
  get 'categoryshow', :on => :collection
end

The section after that discusses adding arbitrary routes if that doesn't meet your exact needs.

Note that the routes file is explicitly ordered: if you try to match a route after something else would have captured it, the first route wins.

Upvotes: 20

Related Questions