views:

139

answers:

1

I upgraded an app I am working on from Rails 3.0.0.beta4 to Rails 3.0.0 and hit an unexpected error. I'm using authlogic for authentication, and after the upgrade the route for new user session form started throwing this error.

undefined method `user_sessions_path'

Ok, I'm using a singular controller name. Not sure what is different between beta4 and the new release that caused the problem.

In my routes.rb file I have this:

  get "user_session/new",     :as => :login
  get "user_session/destroy", :as => :logout
  resources :user_session, :controller => :user_session

Which defines my singular controller routes.

To fix the problem I had to change the first line of the form from this:

<%= form_for @user_session do |f| %>

to this:

<%= form_for @user_session, :url =>  user_session_index_path do |f| %>

What is striking me as weird is the name of the route. Running rake routes revealed the name of the route, but I don't understand why the index was needed. I was expecting something more like user_session_path for the post method. My user_session routes are the only ones acting this way. All of the other are as I expect.

Heres the output from rake routes:

 user_session_index GET    /user_session(.:format)                              {:action=>"index", :controller=>"user_session"}
 user_session_index POST   /user_session(.:format)                              {:action=>"create", :controller=>"user_session"}

This works, but I'm curious to know if anyone else has encountered this.

A: 

First of all, I don't understand, why do you specify the controller name, when it is the same as the resources name? Those two, are equivalent:

resources :user_session, :controller => :user_session
resources :user_session

AFAIR by design create just does POST onto the same path as index. By definition, when controller name is singular, router won't be able to create a plural version of the name. It works the other way around. Thus, theres a _index suffix in both index and create actions.

Singular name would suggest, that the resource is singular, so you should just use (sigular for resource):

resource :user_session

In this case there will be no index action (as it makes no sence for singular resource), and the name for create path will be user_session_path.

As a side note, singular resource doesn't imply, that there is only one instance of the model. It just specifies how do you access the resource. For example you can have multiple users with profiles, but there is perfect sense to use singular resource in order to manage the profiles, since each use can only access his own profile.

ps. I moved on to Devise for authentication before Rails 3 and I don't quite remember how routes used to be solved in Authlogic.

mdrozdziel
Thanks. I had added the plural resources when I was testing to resolve this error: "ActionController::RoutingError (uninitialized constant UserSessionsController)" and forgot to remove it. That explains the index in the path. I still had create the route like this: resource :user_session, :controller => :user_session to resolve the above error. I also still had to provide the :url option for form_for because it really wants a plural resource.
Tim Stephenson