Flowdock
method

resources

Importance_5
v2.3.2 - Show latest stable - 4 notes - Class: ActionController::Resources
resources(*entities, &block) public

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; this is a hash of either
      regular expressions (which must match for the route to match) or extra parameters. For example:
    
        map.resource :profile, :path_prefix => ':name', :requirements => { :name => /[a-zA-Z]+/, :extra => 'value' }
    
      will only match if the first part is alphabetic, and will pass the parameter :extra to the controller.
    
  • :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)

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.

Show source
Register or log in to add new notes.
August 19, 2008 - (v2.1.0)
6 thanks

Namespace or modules in routes

If you have grouped controllers into a module, e.g. admin then you can specify this in the routes using the namespace method:

map.namespace :admin do |admin|
  admin.resources :categories
end

which will map the categories resource giving urls like

/admin/categories/

/admin/categories/new

It will also generate the named routes such as new_admin_category_url and admin_category_path

August 12, 2008
1 thank

Overview of all routes

To see all defined routes type in your console:

rake routes

This produces (eg.):

reorder_toolbox_items   PUT   /toolbox_items reord {:controller=>"toolbox_items", :action=>"reorder"}
channels   GET  /channels {:controller=>"channels", :action=>"index"}
...
etc.
May 6, 2009 - (>= v2.3.2)
1 thank

Formatted route helpers are gone

In Rails >= 2.3 you can’t use formatted_xxx url helpers anymore.

However, you can still pass a :format option to url helpers, eg:

articles_path(:format => :csv) # => /articles.csv
June 13, 2009 - (>= v2.3.2)
0 thanks