Thursday, November 15, 2007

RESTful routing for a singleton resource (singular RESTful routes)

The generated RESTful routes are by default pluralized. So we get routes like /topics/12/posts/4. But what about the routes for resources that are singleton? A user can have a single identity object describing his first name, last name, location etc. We'd like to be able to refer to identities in singular within the context of the logged in user. It would be idiomatically better if the route were /identity/new. In this case map.resource comes to the rescue.

1. On the command line, key in:

ruby script/generate scaffold_resource Identity

2. In config/routes.rb key in:

# map.resources :identities <= comment out automatically added mapping map.resource :identity, :controller => "identities"

3. In the views code, change URLs from identity_path(@identity) etc. to identity_path. E.g. in new.rhtml change the form :url to identity_path from identity_path(@identity)

4. In the controller, which is still called IdentitiesController, "index" action can be removed now since we're only supposed to have one such resource per user. Since we are not passing params[:id] anymore, we need a way to get hold of the Identity object that corresponds to the currently logged in user. This can be done using something like:

@identity = @logged_in_user.identity

assuming @logged_in_user is the currently logged in user and 'has_one' Identity. The idea is to have a means to get the identity object.

5. That's it. You can access URLs such as

http://localhost:3000/identity/new and http://localhost:3000/identity;edit

instead of
http://locahost:3000/identities/new and http://localhost:3000/identities/12;edit

More information on singleton resources can be found in the Rails API documentation. Looking closely at the URLs described in the controllers for map.resource and map.resources in the API documentation clarifies point#3 about removing @identity, that is, params[:id].

0 comments: