Rails路由基础 #

一、路由概述 #

1.1 什么是路由 #

路由是Rails应用的入口,它将URL映射到控制器动作。当用户访问某个URL时,Rails路由系统会解析请求,决定由哪个控制器的哪个动作来处理。

text
请求流程:
浏览器请求 → Rails路由 → 控制器动作 → 视图渲染 → 响应返回

1.2 路由配置文件 #

ruby
# config/routes.rb
Rails.application.routes.draw do
  # 路由定义
end

1.3 查看路由 #

bash
# 查看所有路由
rails routes

# 过滤特定路由
rails routes | grep article

# 以扩展格式显示
rails routes -E

# 只显示特定控制器的路由
rails routes -c ArticlesController

二、基本路由 #

2.1 根路由 #

ruby
# config/routes.rb
Rails.application.routes.draw do
  # 根路由(首页)
  root 'home#index'
  
  # 等价于
  # root to: 'home#index'
end

2.2 GET路由 #

ruby
# config/routes.rb
Rails.application.routes.draw do
  # 基本GET路由
  get 'about', to: 'pages#about'
  
  # 简写形式(控制器#动作)
  get 'contact', to: 'pages#contact'
  
  # 自定义路径
  get 'user/profile', to: 'users#profile'
end

2.3 其他HTTP方法 #

ruby
# config/routes.rb
Rails.application.routes.draw do
  # POST路由
  post 'articles', to: 'articles#create'
  
  # PUT路由(完整更新)
  put 'articles/:id', to: 'articles#update'
  
  # PATCH路由(部分更新)
  patch 'articles/:id', to: 'articles#update'
  
  # DELETE路由
  delete 'articles/:id', to: 'articles#destroy'
  
  # 匹配所有HTTP方法
  match 'photos', to: 'photos#show', via: [:get, :post]
  
  # 匹配所有方法
  match 'photos', to: 'photos#show', via: :all
end

2.4 HTTP方法对照表 #

HTTP方法 用途 Rails路由方法
GET 获取资源 get
POST 创建资源 post
PUT 完整更新 put
PATCH 部分更新 patch
DELETE 删除资源 delete

三、动态路由 #

3.1 动态片段 #

ruby
# config/routes.rb
Rails.application.routes.draw do
  # 动态参数
  get 'articles/:id', to: 'articles#show'
  
  # 多个动态参数
  get 'users/:user_id/articles/:id', to: 'articles#show'
  
  # 在控制器中获取参数
  # params[:id]
  # params[:user_id]
end

3.2 控制器获取参数 #

ruby
# app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
  def show
    @article = Article.find(params[:id])
  end
end

3.3 动态片段约束 #

ruby
# config/routes.rb
Rails.application.routes.draw do
  # 只匹配数字
  get 'articles/:id', to: 'articles#show', constraints: { id: /\d+/ }
  
  # 只匹配特定格式
  get 'users/:id', to: 'users#show', constraints: { id: /[a-z]+/ }
end

四、命名路由 #

4.1 定义命名路由 #

ruby
# config/routes.rb
Rails.application.routes.draw do
  # 命名路由
  get 'about', to: 'pages#about', as: :about
  
  # 根路由自动命名为 root
  root 'home#index'
end

4.2 使用命名路由 #

erb
<!-- 视图中使用 -->
<%= link_to '关于我们', about_path %>
<%= link_to '首页', root_path %>

<!-- 生成完整URL -->
<%= link_to '关于我们', about_url %>
ruby
# 控制器中使用
redirect_to about_path
redirect_to root_url

4.3 路径助手方法 #

路由定义 路径助手 生成的路径
root 'home#index' root_path /
get 'about' about_path /about
get 'articles/:id' article_path(id) /articles/:id

五、资源路由 #

5.1 基本资源路由 #

ruby
# config/routes.rb
Rails.application.routes.draw do
  # 创建完整的RESTful路由
  resources :articles
end

5.2 生成的路由 #

HTTP方法 路径 控制器#动作 路径助手 用途
GET /articles articles#index articles_path 列表
GET /articles/new articles#new new_article_path 新建页面
POST /articles articles#create articles_path 创建
GET /articles/:id articles#show article_path(:id) 详情
GET /articles/:id/edit articles#edit edit_article_path(:id) 编辑页面
PATCH/PUT /articles/:id articles#update article_path(:id) 更新
DELETE /articles/:id articles#destroy article_path(:id) 删除

5.3 限制资源路由 #

ruby
# config/routes.rb
Rails.application.routes.draw do
  # 只生成指定动作的路由
  resources :articles, only: [:index, :show]
  
  # 排除指定动作
  resources :comments, except: [:destroy]
  
  # 只读资源
  resources :pages, only: [:show]
end

5.4 查看生成的路由 #

bash
rails routes | grep articles

# 输出:
#    Prefix Verb   URI Pattern                  Controller#Action
#  articles GET    /articles(.:format)          articles#index
#           POST   /articles(.:format)          articles#create
# new_article GET  /articles/new(.:format)      articles#new
# edit_article GET /articles/:id/edit(.:format) articles#edit
#   article GET    /articles/:id(.:format)      articles#show
#           PATCH  /articles/:id(.:format)      articles#update
#           PUT    /articles/:id(.:format)      articles#update
#           DELETE /articles/:id(.:format)      articles#destroy

六、嵌套资源 #

6.1 基本嵌套 #

ruby
# config/routes.rb
Rails.application.routes.draw do
  resources :articles do
    resources :comments
  end
end

6.2 生成的路由 #

HTTP方法 路径 控制器#动作 用途
GET /articles/:article_id/comments comments#index 文章评论列表
GET /articles/:article_id/comments/new comments#new 新建评论
POST /articles/:article_id/comments comments#create 创建评论
GET /articles/:article_id/comments/:id comments#show 评论详情
GET /articles/:article_id/comments/:id/edit comments#edit 编辑评论
PATCH /articles/:article_id/comments/:id comments#update 更新评论
DELETE /articles/:article_id/comments/:id comments#destroy 删除评论

6.3 使用嵌套路由 #

erb
<!-- 视图中使用 -->
<%= link_to '评论列表', article_comments_path(@article) %>
<%= link_to '添加评论', new_article_comment_path(@article) %>
<%= link_to '评论详情', article_comment_path(@article, @comment) %>
ruby
# 控制器中获取参数
class CommentsController < ApplicationController
  def create
    @article = Article.find(params[:article_id])
    @comment = @article.comments.create(comment_params)
    redirect_to @article
  end
end

6.4 浅层嵌套 #

ruby
# config/routes.rb
Rails.application.routes.draw do
  # 浅层嵌套(避免过深的URL)
  resources :articles do
    resources :comments, shallow: true
  end
end

# 生成的路由:
# POST   /articles/:article_id/comments    comments#create
# GET    /comments/:id                     comments#show
# PATCH  /comments/:id                     comments#update
# DELETE /comments/:id                     comments#destroy

6.5 限制嵌套层级 #

ruby
# config/routes.rb
Rails.application.routes.draw do
  # 只在嵌套中生成部分路由
  resources :articles do
    resources :comments, only: [:index, :new, :create]
  end
  
  resources :comments, only: [:show, :edit, :update, :destroy]
end

七、命名空间 #

7.1 基本命名空间 #

ruby
# config/routes.rb
Rails.application.routes.draw do
  namespace :admin do
    resources :users
    resources :articles
  end
end

7.2 生成的路由 #

HTTP方法 路径 控制器#动作
GET /admin/users admin/users#index
GET /admin/users/new admin/users#new
POST /admin/users admin/users#create

7.3 控制器目录结构 #

text
app/controllers/
├── application_controller.rb
└── admin/
    └── users_controller.rb
ruby
# app/controllers/admin/users_controller.rb
module Admin
  class UsersController < ApplicationController
    def index
      @users = User.all
    end
  end
end

7.4 自定义路径前缀 #

ruby
# config/routes.rb
Rails.application.routes.draw do
  # 自定义路径前缀
  scope path: '/admin' do
    resources :users
  end
  
  # 或使用 as 选项修改路径助手前缀
  scope module: 'admin', path: 'admin', as: 'admin' do
    resources :users
  end
end

八、成员路由和集合路由 #

8.1 成员路由 #

ruby
# config/routes.rb
Rails.application.routes.draw do
  resources :articles do
    # 成员路由(需要ID)
    member do
      get 'preview'
      post 'publish'
      delete 'archive'
    end
  end
end

# 生成的路由:
# GET    /articles/:id/preview    articles#preview
# POST   /articles/:id/publish    articles#publish
# DELETE /articles/:id/archive    articles#archive

8.2 集合路由 #

ruby
# config/routes.rb
Rails.application.routes.draw do
  resources :articles do
    # 集合路由(不需要ID)
    collection do
      get 'search'
      get 'popular'
      post 'bulk_delete'
    end
  end
end

# 生成的路由:
# GET  /articles/search        articles#search
# GET  /articles/popular       articles#popular
# POST /articles/bulk_delete   articles#bulk_delete

8.3 使用示例 #

erb
<!-- 成员路由 -->
<%= link_to '预览', preview_article_path(@article) %>
<%= button_to '发布', publish_article_path(@article), method: :post %>

<!-- 集合路由 -->
<%= link_to '搜索', search_articles_path %>
<%= link_to '热门文章', popular_articles_path %>

九、重定向 #

9.1 基本重定向 #

ruby
# config/routes.rb
Rails.application.routes.draw do
  # 重定向到指定路径
  get 'old-about', to: redirect('/about')
  
  # 重定向到命名路由
  get 'home', to: redirect(root_path)
  
  # 重定向到外部URL
  get 'google', to: redirect('https://google.com')
end

9.2 动态重定向 #

ruby
# config/routes.rb
Rails.application.routes.draw do
  # 使用块进行动态重定向
  get 'users/:name', to: redirect { |params, request|
    "/profiles/#{params[:name]}"
  }
  
  # 带状态码的重定向
  get 'old-page', to: redirect('/new-page', status: 301)
end

十、路由格式 #

10.1 指定格式 #

ruby
# config/routes.rb
Rails.application.routes.draw do
  # 指定响应格式
  get 'articles', to: 'articles#index', defaults: { format: :json }
  
  # 多种格式
  resources :articles, defaults: { format: :html }
end

10.2 格式约束 #

ruby
# config/routes.rb
Rails.application.routes.draw do
  # 限制格式
  resources :articles, constraints: { format: /(html|json|xml)/ }
end

十一、路由约束 #

11.1 基本约束 #

ruby
# config/routes.rb
Rails.application.routes.draw do
  # 参数约束
  get 'articles/:id', to: 'articles#show', constraints: { id: /\d+/ }
  
  # 格式约束
  get 'articles/:id', to: 'articles#show', constraints: { id: /\d+/, format: :json }
end

11.2 请求约束 #

ruby
# config/routes.rb
Rails.application.routes.draw do
  # 子域名约束
  constraints subdomain: 'admin' do
    resources :articles
  end
  
  # IP约束
  constraints ip: '192.168.1.100' do
    get 'admin', to: 'admin#index'
  end
  
  # 多IP约束
  constraints ip: %w[192.168.1.100 192.168.1.101] do
    get 'admin', to: 'admin#index'
  end
end

11.3 高级约束 #

ruby
# config/routes.rb
Rails.application.routes.draw do
  # 使用类约束
  constraints AdminConstraint.new do
    mount Sidekiq::Web => '/sidekiq'
  end
end

# lib/constraints/admin_constraint.rb
class AdminConstraint
  def matches?(request)
    request.session[:user_id].present? &&
      User.find(request.session[:user_id]).admin?
  end
end

十二、路由通配符 #

12.1 通配符片段 #

ruby
# config/routes.rb
Rails.application.routes.draw do
  # 通配符路由(匹配所有路径)
  get 'pages/*path', to: 'pages#show'
  
  # 示例:
  # /pages/about/company  => params[:path] = 'about/company'
  # /pages/help/faq       => params[:path] = 'help/faq'
end

12.2 控制器处理 #

ruby
# app/controllers/pages_controller.rb
class PagesController < ApplicationController
  def show
    @page = Page.find_by(path: params[:path])
    render :not_found unless @page
  end
end

十三、路由最佳实践 #

13.1 路由组织 #

ruby
# config/routes.rb
Rails.application.routes.draw do
  # 根路由
  root 'home#index'
  
  # 公开路由
  resources :articles, only: [:index, :show]
  resources :categories, only: [:index, :show]
  
  # 用户路由
  namespace :users do
    resources :profiles
  end
  
  # 管理后台
  namespace :admin do
    resources :users
    resources :articles
    resources :categories
  end
  
  # API路由
  namespace :api do
    namespace :v1 do
      resources :articles
    end
  end
end

13.2 路由注释 #

ruby
# config/routes.rb
Rails.application.routes.draw do
  # 公开页面
  get 'about', to: 'pages#about'
  get 'contact', to: 'pages#contact'
  
  # 用户认证
  get 'login', to: 'sessions#new'
  post 'login', to: 'sessions#create'
  delete 'logout', to: 'sessions#destroy'
  
  # 文章资源
  resources :articles do
    # 文章评论
    resources :comments, only: [:create, :destroy]
  end
end

十四、总结 #

14.1 核心要点 #

要点 说明
根路由 root 'home#index'
基本路由 get 'path', to: 'controller#action'
资源路由 resources :articles
嵌套资源 resources :articles { resources :comments }
命名空间 namespace :admin { resources :users }
成员路由 member { get 'preview' }
集合路由 collection { get 'search' }

14.2 下一步 #

现在你已经掌握了Rails路由基础,接下来让我们学习 RESTful路由,深入了解REST架构在Rails中的应用!

最后更新:2026-03-28