Rails Routing Guide

Rails router reference: resources, nested routes, member/collection actions, concerns, constraints, namespaces, and route helpers.

1. Resources & REST Routes

# config/routes.rb
Rails.application.routes.draw do
  # Generates 7 standard REST routes
  resources :articles

  # Singular resource (no :id — e.g. user profile)
  resource :profile

  # Only specific actions
  resources :tags, only: [:index, :show]
  resources :sessions, only: [:new, :create, :destroy]

  # Additional actions
  resources :articles do
    member do
      post :publish
      post :unpublish
      get  :preview
    end
    collection do
      get :featured
      get :search
    end
  end
end

# Route helpers generated:
# articles_path          → /articles
# new_article_path       → /articles/new
# article_path(id)       → /articles/:id
# edit_article_path(id)  → /articles/:id/edit
# publish_article_path   → /articles/:id/publish

2. Nested Routes

resources :articles do
  resources :comments, only: [:index, :create, :destroy]
end
# Generates: /articles/:article_id/comments

# Shallow nesting — avoids deeply nested URLs
resources :articles do
  resources :comments, shallow: true
end
# GET /articles/:article_id/comments  (index, new)
# GET /comments/:id                   (show, edit, update, destroy)

# Limit nesting depth (avoid >1 level)
resources :users do
  resources :articles, only: [:index]  # /users/:user_id/articles
end

3. Concerns

# Reusable routing patterns
concern :commentable do
  resources :comments, only: [:index, :create]
end

concern :taggable do
  resources :tags, only: [:index, :create, :destroy]
end

resources :articles,  concerns: [:commentable, :taggable]
resources :photos,    concerns: [:commentable]
resources :videos,    concerns: [:commentable, :taggable]

4. Namespaces & Scopes

# Namespace — path prefix + module prefix
namespace :admin do
  resources :users
  resources :articles
end
# → /admin/users, Admin::UsersController

# Scope — only path prefix
scope :api do
  scope :v1 do
    resources :articles
  end
end
# → /api/v1/articles, ArticlesController

# Module only (no path prefix)
scope module: :api do
  resources :articles
end
# → /articles, Api::ArticlesController

# Path prefix only (no module)
scope '/api/v1' do
  resources :articles
end

5. Constraints

# Param format constraints
resources :articles, constraints: { id: /\d+/ }

# Subdomain constraints
constraints subdomain: "api" do
  resources :articles
end

# Custom constraint class
class JsonFormatConstraint
  def matches?(request)
    request.format.json?
  end
end

constraints(JsonFormatConstraint.new) do
  resources :articles, defaults: { format: :json }
end

# Catch-all route (must be last)
get '*path', to: 'pages#not_found', via: :all

6. REST Routes Generated by resources

HTTP VerbPathActionHelper
GET/articlesindexarticles_path
GET/articles/newnewnew_article_path
POST/articlescreatearticles_path
GET/articles/:idshowarticle_path(id)
GET/articles/:id/editeditedit_article_path(id)
PATCH/PUT/articles/:idupdatearticle_path(id)
DELETE/articles/:iddestroyarticle_path(id)