Beginners question regarding scaffold setup

Hi, I'm trying to build my first rails app but I'm a little confused. From reading various bits of documentation, I was led to believe that the url the user types would mirror the controller/action setup. For example the url 'message/hello' would use the message/hello view and the 'hello' action in the 'message' controller.

I have used a scaffold to create a user model and controller with the default values (new, edit, destroy etc). However, I have added a new view and action to the controller called 'login', but when I type in the url 'users/login', it tries to find a user whose id='login'.

How can I get around this? Thanks.

Dan Smith wrote:

I have used a scaffold to create a user model and controller with the default values (new, edit, destroy etc). However, I have added a new view and action to the controller called 'login', but when I type in the url 'users/login', it tries to find a user whose id='login'.

How can I get around this? Thanks.

This suggests that you are using Rails 2.x and scaffolding has changed a little. Before version 2, the default was to generate routing for "controller/action" type URLs, but from version 2 the default is to generate RESTful URLs.

To see how URLs get mapped, run the following from your application top directory:

rake routes

You'll see a line of the form:

user GET /users/:id {:controller=>"users", :action=>"show"}

This is matched by the URL "/users/login" so this is why you are being sent to the "show" action and it is looking for a user with an id of "login".

These REST URLs are produced by the following line in your config/routes.rb file:

map.resources :users

There are 2 things you can do. To get the style of URLs prior to version 2, comment out this line in the routes.rb file and restart the server. To keep RESTful routes, update the resources line to specify your new action. Actions that work on a specific ID are added with a :member argument, so:

map.resources :users, :member => { :my_action => :get }

means that your application will now accept URLs of the form /users/:id/my_action (the "rake routes" command will show this change to the routes). Alternatively, if the action doesn't require a specific ID, then use the :collection argument:

map.resources :users, :collection => { :my_action => :get }

This means you can access the URL /users/my_action and reach your action. You can change :get to :post if the action must only apply to POST requests. Other possibilities are :put, :delete and :any. You can add both :member and :collection actions if you need to.

Have a look at #resources in the documentation:

http://api.rubyonrails.com/classes/ActionController/Resources.html#M000308

Also search this forum for posts on routes and resources as there have been many posts on the topic. There are also many websites with information about the new scaffolding mechanisms.

This may sound stupid of me, but I didn’t know of that :any option.