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