Creates named routes for implementing verb-oriented controllers for a
collection \resource.
For example:
map.resources :messages
will map the following actions in the corresponding controller:
class MessagesController < ActionController::Base
# GET messages_url
def index
# return all messages
end
# GET new_message_url
def new
# return an HTML form for describing a new message
end
# POST messages_url
def create
# create a new message
end
# GET message_url(:id => 1)
def show
# find and return a specific message
end
# GET edit_message_url(:id => 1)
def edit
# return an HTML form for editing a specific message
end
# PUT message_url(:id => 1)
def update
# find and update a specific message
end
# DELETE message_url(:id => 1)
def destroy
# delete a specific message
end
end
Along with the routes themselves, resources generates named routes for
use in controllers and views. map.resources :messages produces the
following named routes and helpers:
Named Route Helpers
============ =====================================================
messages messages_url, hash_for_messages_url,
messages_path, hash_for_messages_path
message message_url(id), hash_for_message_url(id),
message_path(id), hash_for_message_path(id)
new_message new_message_url, hash_for_new_message_url,
new_message_path, hash_for_new_message_path
edit_message edit_message_url(id), hash_for_edit_message_url(id),
edit_message_path(id), hash_for_edit_message_path(id)
You can use these helpers instead of url_for or methods that take
url_for parameters. For example:
redirect_to :controller => 'messages', :action => 'index'
# and
<%= link_to "edit this message", :controller => 'messages', :action => 'edit', :id => @message.id %>
now become:
redirect_to messages_url
# and
<%= link_to "edit this message", edit_message_url(@message) # calls @message.id automatically
Since web browsers don‘t support the PUT and DELETE verbs, you will
need to add a parameter ‘_method’ to your form tags. The form
helpers make this a little easier. For an update form with a
@message object:
<%= form_tag message_path(@message), :method => :put %>
or
<% form_for :message, @message, :url => message_path(@message), :html => {:method => :put} do |f| %>
or
<% form_for @message do |f| %>
which takes into account whether @message is a new record or not
and generates the path and method accordingly.
The resources method accepts
the following options to customize the resulting routes:
- :collection - Add named routes for other actions that operate on
the collection. Takes a hash of #{action} => #{method}, where
method is :get/:post/:put/:delete, an
array of any of the previous, or :any if the method does not
matter. These routes map to a URL like /messages/rss, with a route of
rss_messages_url.
- :member - Same as :collection, but for actions that
operate on a specific member.
- :new - Same as :collection, but for actions that operate
on the new \resource action.
- :controller - Specify the controller name for the routes.
- :singular - Specify the singular name used in the member routes.
- :requirements - Set custom routing parameter requirements.
- :conditions - Specify custom routing recognition conditions. \Resources sets the :method value for the
method-specific routes.
- :as - Specify a different \resource name to use in the URL path. For
example:
# products_path == '/productos'
map.resources :products, :as => 'productos' do |product|
# product_reviews_path(product) == '/productos/1234/comentarios'
product.resources :product_reviews, :as => 'comentarios'
end
- :has_one - Specify nested \resources, this is a shorthand for
mapping singleton \resources beneath
the current.
- :has_many - Same has :has_one, but for plural \resources.
You may directly specify the routing association with has_one and
has_many like:
map.resources :notes, :has_one => :author, :has_many => [:comments, :attachments]
This is the same as:
map.resources :notes do |notes|
notes.resource :author
notes.resources :comments
notes.resources :attachments
end
- :path_names - Specify different names for the ‘new’
and ‘edit’ actions. For example:
# new_products_path == '/productos/nuevo'
map.resources :products, :as => 'productos', :path_names => { :new => 'nuevo', :edit => 'editar' }
You can also set default action names from an environment, like this:
config.action_controller.resources_path_names = { :new => 'nuevo', :edit => 'editar' }
- :path_prefix - Set a prefix to the routes with required route
variables.
Weblog comments usually belong to a post, so you might use resources like:
map.resources :articles
map.resources :comments, :path_prefix => '/articles/:article_id'
You can nest resources calls
to set this automatically:
map.resources :articles do |article|
article.resources :comments
end
The comment \resources work the same,
but must now include a value for :article_id.
article_comments_url(@article)
article_comment_url(@article, @comment)
article_comments_url(:article_id => @article)
article_comment_url(:article_id => @article, :id => @comment)
If you don‘t want to load all objects from the database you might
want to use the article_id directly:
articles_comments_url(@comment.article_id, @comment)
- :name_prefix - Define a prefix for all generated routes, usually
ending in an underscore. Use this if you have named routes that may clash.
map.resources :tags, :path_prefix => '/books/:book_id', :name_prefix => 'book_'
map.resources :tags, :path_prefix => '/toys/:toy_id', :name_prefix => 'toy_'
You may also use :name_prefix to override the generic named routes
in a nested \resource:
map.resources :articles do |article|
article.resources :comments, :name_prefix => nil
end
This will yield named \resources like
so:
comments_url(@article)
comment_url(@article, @comment)
- :shallow - If true, paths for nested resources which reference a specific
member (ie. those with an :id parameter) will not use the parent path
prefix or name prefix.
The :shallow option is inherited by any nested resource(s).
For example, ‘users’, ‘posts’ and
‘comments’ all use shallow paths with the following nested resources:
map.resources :users, :shallow => true do |user|
user.resources :posts do |post|
post.resources :comments
end
end
# --> GET /users/1/posts (maps to the PostsController#index action as usual)
# also adds the usual named route called "user_posts"
# --> GET /posts/2 (maps to the PostsController#show action as if it were not nested)
# also adds the named route called "post"
# --> GET /posts/2/comments (maps to the CommentsController#index action)
# also adds the named route called "post_comments"
# --> GET /comments/2 (maps to the CommentsController#show action as if it were not nested)
# also adds the named route called "comment"
You may also use :shallow in combination with the has_one
and has_many shorthand notations like:
map.resources :users, :has_many => { :posts => :comments }, :shallow => true
- :only and :except - Specify which of the seven default
actions should be routed to.
:only and :except may be set to :all,
:none, an action name or a list of action names. By default,
routes are generated for all seven actions.
For example:
map.resources :posts, :only => [:index, :show] do |post|
post.resources :comments, :except => [:update, :destroy]
end
# --> GET /posts (maps to the PostsController#index action)
# --> POST /posts (fails)
# --> GET /posts/1 (maps to the PostsController#show action)
# --> DELETE /posts/1 (fails)
# --> POST /posts/1/comments (maps to the CommentsController#create action)
# --> PUT /posts/1/comments/1 (fails)
The :only and :except options are inherited by any nested
resource(s).
If map.resources is called with multiple resources, they all get the same options
applied.
Examples:
map.resources :messages, :path_prefix => "/thread/:thread_id"
# --> GET /thread/7/messages/1
map.resources :messages, :collection => { :rss => :get }
# --> GET /messages/rss (maps to the #rss action)
# also adds a named route called "rss_messages"
map.resources :messages, :member => { :mark => :post }
# --> POST /messages/1/mark (maps to the #mark action)
# also adds a named route called "mark_message"
map.resources :messages, :new => { :preview => :post }
# --> POST /messages/new/preview (maps to the #preview action)
# also adds a named route called "preview_new_message"
map.resources :messages, :new => { :new => :any, :preview => :post }
# --> POST /messages/new/preview (maps to the #preview action)
# also adds a named route called "preview_new_message"
# --> /messages/new can be invoked via any request method
map.resources :messages, :controller => "categories",
:path_prefix => "/category/:category_id",
:name_prefix => "category_"
# --> GET /categories/7/messages/1
# has named route "category_message"
The resources method sets
HTTP method restrictions on the routes it generates. For example, making an
HTTP POST on new_message_url will raise a RoutingError exception.
The default route in config/routes.rb overrides this and allows
invalid HTTP methods for \resource
routes.