Rails and Restful Authentication

It’s been quite a while since my last Ruby on Rails post so let’s go over a little “gotcha” that you might encounter when using the restful_authentication plugin.

Getting started with restful_authentication is fairly easy.  After installing the plugin it’s just a matter of running the following generate command:

script/generate authenticated user sessions

This will create a migration for a users table, a model and controller for users and a sessions controller.  It will also add some named routes to config/routes.rb.

So far so good, right?  Well, a common mistake when generating the model and controllers is to user the singular form of both user and session.  The command will run successfully and do exactly what you told it to do.  You won’t become aware of a problem until you try to log in for the first time and see this:

NameError in SessionsController#create

uninitialized constant SessionsController

RAILS_ROOT: C:/rails/bookmarks

Application Trace | Framework Trace | Full Trace


Request

Parameters:

{"commit"=>"Log in",
"authenticity_token"=>"0c0f07222da8ed58d8c6ebcafb9bf32f0bc84143",
"login"=>"anthony",
"password"=>"mysupersecretpassword"}

Uh oh! what went wrong?  It looks like Rails is looking for a controller called SessionsController.  But we generated one named SessionController.  Why is this happening?  Take a look in the views/session/new.html.erb file.

<% form_tag session_path do -%>
<p><label for="login">Login</label><br/>
<%= text_field_tag 'login' %></p>
<p><label for="password">Password</label><br/>
<%= password_field_tag 'password' %></p>
<!-- Uncomment this if you want this functionality
<p><label for="remember_me">Remember me:</label>
<%= check_box_tag 'remember_me' %></p>
-->
<p><%= submit_tag 'Log in' %></p>
<% end -%>

The form_tag target is session_path.  session_path is created for us by magic because of its mapping in routes.rb.

map.resource :session

When mapping a resource like this Rails looks for the controller with the pluralized name of the resource name by default, which means session_path is getting SessionsController.  We can change the behavior by explicitly setting the controller for the resource.

map.resource :session, :controller => :session

Try to log in again and you will be authenticated!  Of course it may just be easier to remember to use the pluralized name of whatever controller you want to use for managing sessions.

1 comment so far ↓

#1 dyepmulley on 08.03.08 at 12:18 pm

Very nice!!

Leave a Comment