前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Rails路由

Rails路由

作者头像
用户1515472
发布于 2019-07-24 06:22:50
发布于 2019-07-24 06:22:50
4.8K00
代码可运行
举报
运行总次数:0
代码可运行

资源路由

一行代码完成资源资源路由声明:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
resources :photos

这会创建7个不同的路由,这些路由会映射到 Photos 控制器上。

这样4个URL地址就会映射到7个不同的控制器动作上。

用于生成路径和URL地址的辅助方法

在创建资源路由时,会同时创建多个可以在控制器中使用的辅助方法,如上面的资源路由会创建以下方法:

  • photos_path:返回值为 /photos
  • new_photos_path:返回值为 /photos/new
  • edit_photo_path(:id):返回值为 /photos/:id/edit
  • photo_path(:id):返回值为 /photos/:id

这些方法都有对应的_url形式(photos_url),前者返回的是路径,后者返回的是完整的url地址。

同时定义多个资源

可以同时定义多个资源路由:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
resources :photos, :books, :videos

等价于:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
resources :photos
resources :books
resources :videos
单数资源

使用 resource 方法可以创建单数资源,这会创建6个不同的路由:

有时候在复数资源中希望能够不使用ID就能查找资源,如显示当前登录用户的信息:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
get 'profile', to: 'users#show'

如果 get 方法的to选项的值是字符串,那么这个字符串应该使用controller#action形式,如果是表示动作的符号,则还需要添加controller选项:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
get 'profile', to: :show, controller: 'users'
控制命名空间和路由

把控制器放入同一命名空间是非常常见的,如将管理员有关的控制器置于 Admin:: 命名空间中,这样可以把控制器文件放在 app/controllers/admin 文件夹中,在路由中这样声明:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
namespace :admin do
    resources :articles, :comments
end

对于articles资源

如果想把 /articles 路径(不带/admin前缀)映射到Admin::Articles控制器上,可以这样声明:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
scope module: 'admin' do
    resources :articles, :comments
end

或者

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
resources :articles, module: 'admin'
resources :articles, module: 'admin'

或者:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
resources :articles, path: '/admin/articles'
嵌套资源

有些资源是其他资源的子资源,这种情况非常常见:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Magazine < ApplicationRecord
    has_many :ads
end

class Ad < ApplicationRecord
    belongs_to :magazine
end

通过嵌套路由来反映模型关联:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
resources :magazine do
    resources :ads
end

对于嵌套路由,可以不断嵌套:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
resources :publishers do
    resources :magazine do
        resources :photos
    end
end

但是显然嵌套太深是非常麻烦的,经验告诉我们嵌套资源层级不应该超过一层,而避免嵌套过深的方法之一就是把动作集合放在父资源中,这样既可以表明层级关系,又不必嵌套成员动作:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
resources :articles do
    resources :comments, only: [:index, :new, :create]
end

resources :comments, only: [:show, :edit, :update, :destroy]

当然,使用 :shallow 选项可以简化上面的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
resources :articles do
    resources :comments, shallow: true
end

当然,在复选项中使用 :shallow 选项,这样会在所有的子资源中使用 :shallow 选项:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
resources :articles, shallow: true do
    resources :comments
    resources :quotes
end

也可以使用 shallow 方法创建作用域,使得所有嵌套均为浅层嵌套:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
shallow do
  resources :articles do
    resources :comments
    resources :quotes
    resources :drafts
  end
end

使用scope方法也可以来定义浅层路由,且有两个选项,:shallow_path 选项会为成员路径添加前缀:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
scope shallow_path: "sekret" do
  resources :articles do
    resources :comments, shallow: true
  end
end

:shallow_prefix 选项会为具名方法添加指定前缀:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
scope shallow_prefix: "sekret" do
  resources :articles do
    resources :comments, shallow: true
  end
end
路由concern

路由concern用于声明公共路由,公共路由可以在其他资源和路由中重复使用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
concern :commentable do
    resources :comments
end

concern :image_attachable do
    resources :images, only: :index
end

使用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
resources :messages, concerns: :commentable

resources :articles, concerns: [:commentable, :image_attachable]

相当于:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
resources :messages do
    resources :comments
end

resources :articles do
    resources :comments
    resources :images, only: :index
end
从对象创建路径和RUL地址

除了使用路由辅助方法,Rails还可以从参数数组创建路径和URL地址,假如有以下路由:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
resources :magazine do
    resources :ads
end

使用 magazine_ad_path 方法时,可以传入Magazine和Ad的实例,而不只是数字ID:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<%= link_to 'Ad details', magazine_ad_path(@magazine, @ad) %>

还可以使用 url_for 方法时传入一组对象,Rails会自动确定对应的路由:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<%= link_to 'Ad details', url_for([@magazine, @ad]) %>

Rails能够识别各个实例,自动使用 magazine_ad_path 辅助方法。当然在使用 link_to 等辅助方法时,可以只指定对象,而不必完整调用 url_for 方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<%= link_to 'Ad details', [@magazine, @ad] %>
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<%= link_to 'Magazine details', @magazine %>

如果想要链接到其他控制器动作,只需把动作名称作为第一个元素插入对象数组即可:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<%= link_to 'Edit Ad', [:edit, @magazine, @ad] %>

这样就可把模型实例看做URL地址,这是使用资源式风格最关键的优势之一。

非资源式路由

和资源路由自动生成一系列路由不同,这时需要分别声明各个路由,非资源路由可以把任意URL地址映射到控制器动作的路由。

绑定参数

声明普通路由时,可以使用符号作为参数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
get 'photos(/:id)', to: :display

在处理 /photos/1 请求时,会把请求映射到 Photos 控制器的 display 动作上,并把参数1传入params[:id],并将路由映射到 PhotosController#display 上,并且 /photos 请求也会映射到这个控制器动作上,因为 :id 在括号中,是可选参数。

动态片段

声明普通路由时,允许使用多个动态片段,动态片段会传入params,以便在控制器动作中使用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
get 'photos/:id/:user_id', to: 'photos#show'

/photos/1/2 请求会被映射到 photos#show 动作上,这时 params[:id] 的值是 1 ,params[:user_id] 的值是 2

查询字符串

params 也包含了查询字符串中的所有参数,如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
get 'photos/:id', to: 'photos#show'

/photos/1?user_id=2 请求也会映射到 Photos#show 控制器动作上,这时params的值是

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{controller: 'photos', action: 'show', id: '1', user_id: '2'}
定义默认值

:defaults 选项设定的散列为路由定义默认值,未通过动态片段定义的参数也可以指定默认值

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
get 'photos/:id', to: 'photos#show', defaults: {format: 'jpg'}

Rails会把 /photos/12 路径映射到 Photos#show 动作上,并把 params[:format] 设为 'jpg'

当然 defaults 还有块的形式,可以为多个路由定义默认值:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
defaults format: :json do
    resources :photos
end

当然需要注意的是查询参数是不会覆盖默认值的

为路由命名

可以使用 :as 选项来为路由命名

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
get 'exit', to: 'sessions#destroy', as: :logout

这个路由声明会创建 logout_path 和 logout_url 这两个具名辅助方法

路由命名可以覆盖资源路由定义的路由辅助方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
get ':username', to: 'users#show', as: :user
HTTP方法约束

通过使用 match 方法和 :via 选项,可以一次匹配多个HTTP方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
match 'photos', to: 'photos#show', via: [:get, :post]

通过 via: :all 选项,路由可以匹配所有的HTTP方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
match 'photos', to: 'photos#show', via: :all

把GET和POST请求映射到同一个控制器动作上会带来安全隐患,通常我们应该避免将不同的HTTP方法映射到同一个控制器动作上。

片段约束

使用 :contraints 选项可以约束动态片段的格式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
get 'photos/:id', to: 'photos#show', contraints: { id: /[A-Z]\d{5}/ }

这个路由会匹配 /photos/A12345 路径,但不会匹配 /photos/893 路径,这个还可以简写为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
get 'photos/:id', to: 'photos#show', id: /[A-Z]\d{5}/

:contraints 选项的值可以是正则表达式,但不能使用 ^ 符号,比如下面就是错误的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
get '/:id', to: 'articles#show', constraints: { id: /^\d/ }
路由通配符和通配符片段

路由通配符用于指定特殊参数,这个参数会匹配路由的所有剩余部分:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
get 'photos/*other', to: 'photos#unknown'

这个路由会匹配 photos/12 和 /photos/long/path/to/12 路径,并把 params[:other] 分别设置为 "12" 和 "long/path/to/12"。像 *other 这样以星号开头的片段,称作“通配符片段”。

通配符片段可以出现在路由中的任何位置:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
get 'books/*section/:title', to: 'books#show'
重定向

在路由中可以使用 redirect 辅助方法进行重定向

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
get '/stories', to: redirect('/articles')

重定向中也可以使用源路径的动态片段:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
get '/stories/:name', to: redirect('/articles/%{name}')

redirect 默认是301永久重定向,有些浏览器和代理服务器缓存这种类型的重定向,从而导致无法访问重定向前的网页,为了避免这种情况,我们可以使用 :status 选项修改响应状态:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
get '/stories/:name', to: redirect('/stories/%{name}'), status: 302
使用 root 方法

root 方法指明如何处理根路径的请求:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
root to: 'pages#main'

简易写法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
root 'pages#main'

root路由只处理 GET 请求

unicode 字符路由

声明路由时,可以直接使用 Unicode 字符:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
get "忽如寄" , to: 'welcome#index'

自定义资源路由

指定控制器

:controller 选项用于显式指定资源使用的控制器:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
resources :photos, controller: 'images'

这时路由会把 /photos 路径映射到 Images 控制器上

对于命名空间中的控制器,可以使用目录表示法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
resources :user_permissions, controller: 'admin/user_permissions'
指定约束

:constraints 选项用于指定隐式 ID 必须满足格式要求

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
resources :photos, constraints: {id: /[A-Z][A-Z][0-9]+/ }

这时会约束 :id 参数,路由不会匹配 /photos/1 路径,会匹配 /photos/PR12

当然也可以同时约束多个路由:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
constraints(id: /[A-Z][A-Z][0-9]+/) do
    resources :photos
    resources :accounts
end
覆盖具名路由辅助方法
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
resources :photos, as: 'images'

此时的具名辅助方法被修改为:

覆盖 new 和 edit 片段

:path_names 选项用于覆盖路径中自动生成的 new 和 edit 片段

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
resources :photos, path_names: { new: 'make', edit: 'change' }

这个路由能够识别以下路径:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/photos/make

/photos/1/change

:path_names 选项不会改变控制器动作的名称,仍然映射到 new 和 edit 动作上

限制创建的路由

Rails 默认会为每个 REST 式路由创建7个默认动作,可以使用 :only:except 选项来微调此行为。 :only 选项用于指定想生成的路由:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
resources :photos, only: [:index, :show]

:except 选项用于指定不想生成的路由:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
resources :photos, except: :destroy
本地化路径

使用 scope 方法,可以修改 resources 方法生成的路径名称:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
scope(path_names: {new: 'neu', edit: 'bearbeiten'}) do
    resources :categories, path: 'kategorien'
end
嵌套资源使用 :as 选项

这会覆盖自动生成的辅助方法名称:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
resources :magazine do
    resources :ads, as: 'periodical_ads'
end

这会生成 magazine_periodical_ads_url 等辅助方法。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
thinkphp 路由
http://localhost:8082/admin/blog/23/ 此时会匹配23内容
mySoul
2019/05/30
1.2K0
【ASP.NET Core 基础知识】--路由和请求处理--Attribute路由
在ASP.NET Core中,路由是将传入的URL请求映射到正确的控制器和操作的方法。Attribute路由是一种基于属性,用于定义路由规则的方式,通过在控制器类和操作方法上应用特定的属性,来定义URL模板。
喵叔
2024/05/24
2760
Rails 构建评论功能(5)
修改视图和控制器 [root@h202 blog]# vim app/views/articles/show.html.erb [root@h202 blog]# cat app/views/articles/show.html.erb <p> <strong>Title:</strong> <%= @article.title %> </p> <p> <strong>Text:</strong> <%= @article.text %> </p> <h2>Add a commen
franket
2021/10/20
3540
Rails MVC 和 CRUD(14)
删除文章 在 controllers 中定义 destory 方法 然后在 index 视图中加入 Destroy 链接 [root@h202 blog]# vim app/controllers/articles_controller.rb [root@h202 blog]# cat app/controllers/articles_controller.rb class ArticlesController < ApplicationController def new @article
franket
2021/11/25
2380
Rails 构建评论功能(7)
再次访问,显示效果不变 再将评论的表单也抽出 [root@h202 blog]# vim app/views/comments/_form.html.erb [root@h202 blog]# cat app/views/comments/_form.html.erb <%= form_for([@article, @article.comments.build]) do |f| %> <p> <%= f.label :commenter %><br> <%= f.text_fiel
franket
2021/10/20
4400
Spiral 详细上手指南之路由规则
在上一篇《Spiral 详细上手指南之安装与配置》中,我们已经基于官方的 WEB 项目模板创建了自己的本地项目 "myapp" 并且已经配置好了数据库连接和用于开发的进程参数。
小李刀刀
2020/03/04
1.4K0
Spiral 详细上手指南之路由规则
Rails MVC 和 CRUD(10)
再次加载 可以成功显示了 ---- 列出所有文章 [root@h202 blog]# vim app/controllers/articles_controller.rb [root@h202 blog]# cat app/controllers/articles_controller.rb class ArticlesController < ApplicationController def new end def create # render plain: params[:ar
franket
2021/11/25
2070
3分钟短文:Laravel路子真野啊!路由昵称前缀中间件
上一章内容我们介绍了使用laravel路由动词定义方便的url,以及通过url参数绑定传递数据, 本文我们继续深入Route功能,学习一些提升生产力的方法,在现实场景中也非常实用。
程序员小助手
2020/10/20
1.7K0
3分钟短文:Laravel路子真野啊!路由昵称前缀中间件
Rails 构建评论功能(6)
如果程序中重复代码达到一定量级,会影响可读性和可维护性,这时我们可以将其中重复部分抽出来,单独成块
franket
2021/10/20
4850
Rails MVC 和 CRUD(12)
保存成功就直接显示,如果保存失败,就重绘 new 页面,new 页面中加入了对错误信息的显示
franket
2021/11/25
2830
ASP.NET MVC5高级编程 ——(5)路由
这章呢,我们开始讲ASP.NET MVC5中的路由机制,在这之前,先提一下URL(Uniform Resource Locator)-- 统一资源定位符。需要注意的是,这里的“资源”这个词,是一个抽象的概念,既可以指一个文件,也可以指一个方法、一个类或是一段代码。由此我们引出了路由的主要用途:
浩Coding
2019/07/03
2.1K0
跟我学Spring Cloud(Finchley版)-17-Zuul路由配置详解
默认的路由规则是:访问 $ZUUL_URL/指定为服务/** 会被转发到 指定微服务 的 /** 。
用户1516716
2019/07/10
8850
Rails里应用Devise
Use Devise For Authentication Devise is great gem for authentication, check out here. Add Gem First thing you need to do is to add devise gem to you Gemfile. Just add gem 'devise', '~> 3.5' to your Gemfile and run bundle install and restart your server. Se
用户2183996
2018/06/28
3700
使用rails实现最简单的CRUD
这里定义了路由hello/index,并且使用root方法将首页修改为了hello控制器下的index方法,也就是两路由的控制器一致。
用户1515472
2019/07/24
3.4K0
Asp.Net Web API 2第五课——Web API路由
    Asp.Net Web API第一课——入门 http://www.cnblogs.com/aehyok/p/3432158.html
aehyok
2018/08/31
1.3K0
Asp.Net Web API 2第五课——Web API路由
AngularJS爬坑之路——路由关于路由的那点事儿
关于路由,首先想到的是生活中的路由器。 类似路由器,AngularJS中的路由其实也是一样的概念
大牧莫邪
2018/08/27
1.6K0
【大家的项目】Salvo - 一个简单的 Web 后端框架
为什么要写这个框架 因为我笨,无法学会使用 actix-web 等现存的框架。当我想把以前的 go 的 web 服务使用 rust 实现时,一眼看去,似乎每个框架都比 go 里存在框架复杂, 本来 R
MikeLoveRust
2021/09/08
8830
Rails MVC 和 CRUD(4)
结果展示了当前的一系列 Restfull API 与 Controller#Action 的对应关系
franket
2021/11/24
4400
【ASP.NET Core 基础知识】--路由和请求处理--路由概念(一)
在Web应用中,路由是一个至关重要的概念,它负责将用户的请求映射到相应的处理程序,以确保正确的页面或资源被呈现给用户。通过将用户请求与适当的处理程序关联起来,使得应用能够以有序和可维护的方式响应用户的操作。
喵叔
2024/01/18
6160
zend framework项目分组(初级版)
Zend_Controller_Front 控制了Zend_Controller系统的整个工作流。它是前端控制器(FrontController)模型的解释。Zend_Controller_Front处理所有由服务器接收的请求并负责把请求派发给动作控制器 Zend_Controller_Request_Abstract (often referred to as the Request Object)描述请求环境和提供设置和读取控制器和动作名字以及任何请求参数的方法。另外它跟踪它所包含的动作是否被Zend_
苦咖啡
2018/05/08
7980
zend framework项目分组(初级版)
相关推荐
thinkphp 路由
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验