Adding an action to an existing controller (Ruby on Rails)
Solution 1
Your routing isn't set up to allow that route. Assuming you're using the default scaffolding, put this line before the map.resources :posts
line in config/routes.rb:
map.connect "posts/:action", :controller => 'posts', :action => /[a-z]+/i
The regex for :action
restricts it to just a-z (to avoid catching things like /posts/1). It can be improved if you need underscores or numbers in your new actions.
Solution 2
The error you're making is actually a pretty common one.
Basically, Rails automatically maps URLs for your scaffolds. So when you created the Posts scaffolds, Rails is mapping the URL routes for it. One such route is the URL for viewing a single post: /posts/(post_id)
So, when you're entering the URL /posts/start Rails thinks you're saying "Hey, give me the post with ID = start. So Rails complains that the show method can't find a post with such ID.
One quick way to fix this is to make sure your config/routes.rb has the route for the start action before the scaffolding routes:
# Route for start action
map.connect '/posts/start', :controller => 'posts', :action => 'start'
# Default mapping of routes for the scaffold
map.resources :posts
Anyway, hope that helps.
Solution 3
On Rails 4.x use:
get '/posts/start', :controller => 'posts', :action => 'start'
On Rails 3.x use:
match '/posts/start', :controller => 'posts', :action => 'start'
instead of
map.connect '/posts/start', :controller => 'posts', :action => 'start'
it solved my issue.
Solution 4
Try this if you are using rails 3.0.3
in your route.rb
resource :posts do
collection do
get 'start'
end
end
this might help
Solution 5
I want to say, sometimes Rails gets sticky with routes-caching, even in the development environment.
It may help to restart your Rails server. This has worked for me more times than I can count when receiving this error.
Mark
Updated on March 31, 2020Comments
-
Mark about 4 years
I am new to Ruby on Rails, I have completed the Blog Tutorial.
I am now trying to add an additional action to the controller, called 'start'.
def start end
I have added a view page "app/views/posts/start.html.erb" containing nothing but simple html.
When I go to /posts/start i get the following error.
ActiveRecord::RecordNotFound in PostsController#show Couldn't find Post with ID=start
I understand the error, the show action is being executed and start is not a valid ID. Why doesn't the start action get executed, is there some part of the MVC architecture or configuration I am missing ?
Below is my posts_controller.rb
class PostsController < ApplicationController # GET /posts/start def start end # GET /posts # GET /posts.xml def index @posts = Post.find(:all) respond_to do |format| format.html # index.html.erb format.xml { render :xml => @posts } end end # GET /posts/1 # GET /posts/1.xml def show @post = Post.find(params[:id]) respond_to do |format| format.html # show.html.erb format.xml { render :xml => @post } end end end
Yes I have restarted the server and tried it with Mongrel and webrick.
-
Mark over 15 yearsThanks for the explanation, I'll have to read up more on routes.
-
David over 15 yearsI think one of the things that help most when trying to understand how routes work in RoR is to remember that they get evaluated top to bottom. So it is generally a best practice to have your more specific routes before the general (catch-all) routes.
-
rxgx over 12 yearsIn Rails 3, this adds
"collection"=>{"my_action"=>:get}
to the GET params. -
rxgx over 12 yearsIn Rails 3, the collection option adds
"collection"=>{"my_action"=>:get}
to the GET params. -
Ira Herman over 11 yearsI used match '/pages/action', :controller => 'pages', :action => 'action' and it worked.