Advanced Rails - Building Industrial-Strength Web Apps in Record Time

(Tuis.) #1
RESTful Rails | 215

nested, and friends are always scoped to a person, it may make more sense to use
controller namespaces. This would involve changingFriendsControllertoPeople::
FriendsController and moving it to app/controllers/people/friends_controller.rb.
Then, the route declaration should be changed to:


map.resources :people do |person|
person.resources :friends, :controller => 'people/friends',
:name_prefix => 'person_'
end

Thename_prefixoption adds a prefix to the generated routes. In this case, adding
that option to theperson.resourcesline gives us named routes likepersonfriends
pathandperson_friend_pathinstead offriends_pathandfriend_path, which better
reflects the new scoping of our resources.


There is apath_prefixoption that will add a prefix to the URIs that the route will
recognize and generate. This comes with nested routes—you don’t have to do any-
thing. The nested routes above could be manually specified as follows:


map.resources :people
map.resources :friends, :controller => 'people/friends',
:name_prefix => 'person_',
:path_prefix => '/people/:person_id'

This usage is not as pretty, but it affords more control over the parameter names
your controller is passed. This method makes more sense if the IDs being used in the
routes are something other than ActiveRecord numeric primary keys.


Singleton resource routes


Sometimes, there will be an entity that exists as a singleton, such that there will only
be one in existence within its containing scope. An example would be a subscription
user’s account, which contains billing information. This information is modeled as
a separate resource from the user’s other data. In contrast to the collection
resource/users/1/postsand its member/users/1/posts/1, we have the singleton
resource/users/1/account.


Rails provides a way to map singleton resources with themap.resourcestatement (in
parallel tomap.resourcesfor collections of resources). The resource name is still sin-
gular, but the inferred controller name is plural. Our routing statement for the pre-
ceding example would be:


map.resources :users do |user|
user.resource :account
end

This code would expect an AccountsController to contain the user account actions.
Singleton resources contain the same methods as collection resources, but with no
index action.

Free download pdf