views:

4572

answers:

5

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.

+10  A: 

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.

zenazn
+15  A: 

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.

Dave
Thanks for the explanation, I'll have to read up more on routes.
Mark Robinson
I 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.
Dave
A: 

I really have tried yours solutions, showed here but i don't know why it hasn't worked out!

Thiago Diniz
You should ask a new question and reference this question in it.. you may have a different problem then I did.
Mark Robinson
Actually it tried to do exactly the same as you in a rails project, so i don't see any reason to ask a new question.
Thiago Diniz
This shouldn't be an answer. Think: does this help deal with the original poster's question? As Mark Robinson said, this should be asked in a new question, EVEN IF it seems to be the same. And if you know it is the same, then just sit back and watch the answers come in. You contribute *nothing* by answering with an "I don't know".
Platinum Azure
in fact this is not an answer, but think with me: if I ask the same question someone will acuse me of asking duplicate question. So I had to say that this is not an general solution of this problem!
Thiago Diniz
A: 

I found the solution to my problem, in the routes.rb file where

map.resource :post

I added with collection argument, so it stayed this way:

map.resource :post, :collection => { :my_action => :get}
Thiago Diniz
+1  A: 

I can't vote yet - but this works: map.resource :post, :collection => { :my_action => :get}

chernia