路由相关的类和模块在命名空间 ActionDispatch::Routing::Mapper 中,这里我给一个它的链接方便在学习时查看
匹配一个 URL 模式到一个或多个路由
基础使用
# 匹配格式为 :controller/:action. 请注意这样使用路由不能带参数
match 'account/setting', via: :get
| Prefix | Verb | URI Pattern | Controller#Action |
|---|---|---|---|
| account_setting | GET | /account/setting(.:format) | account#setting |
带参数的路由
# 带参数的路由必须指定 :to 参数, 他才能正确匹配到指定的 controller 和 action
match 'account/setting/:id', to: "account#setting", via: :get
| Prefix | Verb | URI Pattern | Controller#Action |
|---|---|---|---|
| GET | /account/setting/:id(.:format) | account#setting |
在路由匹配中使用通配符并且映射到params中
match 'songs/*category/:title', to: 'songs#show', via: :get
| Prefix | Verb | URI Pattern | Controller#Action |
|---|---|---|---|
| GET | /songs/*category/:title(.:format) | songs#show |
上面的通配符路由会将songs/rock/classic/stairway-to-heaven路径做匹配和映射
<ActionController::Parameters {"controller"=>"songs", "action"=>"show", "category"=>"rock/classic/abc", "title"=>"stairway-to-heaven"} permitted: false>
路由映射到 controller 和 action 的几种写法
# 短写形式, match的第一个参数传递一个hash用来映射对应的路由和控制器
match 'photos/:id' => 'photos#show', via: :get
# 我们上面一直使用的正常模式(比较直观)
match 'photos/:id', to: 'photos#show', via: :get
# 冗余模式, 所有的参数都通过options来指定
match 'photos/:id', controller: 'photos', action: 'show', via: :get
除了以上match的几种使用方法外,还可以指定兼容Rack方式的路由
match 'photos/:id', to: -> (hash) { [200, {}, ['Coming soon']] }, via: :get
路由对应控制器名称
路由对应控制器里的方法名称
可以用于覆盖资源默认的:id参数,一但覆盖你可以在控制的方法中使用params[:param]去访问
resources :photos, param: :title
| Prefix | Verb | URI Pattern | Controller#Action |
|---|---|---|---|
| photos | GET | /photos(.:format) | photos#index |
| POST | /photos(.:format) | photos#create | |
| new_photo | GET | /photos/new(.:format) | photos#new |
| edit_photo | GET | /photos/:title/edit(.:format) | photos#edit |
| photo | GET | /photos/:title(.:format) | photos#show |
| PATCH | /photos/:title(.:format) | photos#update | |
| PUT | /photos/:title(.:format) | photos#update | |
| DELETE | /photos/:title(.:format) | photos#destroy |
嗯我们看到之前默认:id已经被替换为了:title
为了更好配合上面路由的使用方法,你还可以覆盖对应模型的to_param方法,去构造符合路由的 url
class Photo < ActiveRecord::Base
def to_param
name
end
end
photo = Photo.find_by(name: 'ruby-china')
photo_path(photo) # => "/photos/ruby-china"
路由的前缀
控制器的命名空间,这里暂时还没懂。稍后补上
设置生成路由辅助函数的名称
match "account/setting", via: :get
match "account_as/setting_as", as: 'setting', via: :get
| Prefix | Verb | URIPattern | Controller#Action |
|---|---|---|---|
| account_setting | GET | /account/setting(.:format) | account#setting |
| setting | GET | /account_as/setting_as(.:format) | account_as#setting_as |
通过上面的输出可以看出,我们将account_as/setting_as路由的生成函数定义为了setting, 在代码中就可以这样使用setting_url setting_path
定义路由所匹配的动作 (verbs), 相关动作资料可以看这里
match 'path', to: 'c#a', via: :get # get
match 'path', to: 'c#a', via: [:get, :post] # get/post
match 'path', to: 'c#a', via: :all # all http verb
可以为 resource(s) 定义的资源增加:member, :collection, :new路由。请注意这个必须在resource(s)的 do 语句块中使用
resources :photos do
match 'preview', to: 'photos#preview', on: :new, via: :get
match 'preview', to: 'photos#preview', on: :member, via: :get
match 'preview', to: 'photos#preview', on: :collection, via: :get
end
也等同于如下书写方法
resources :photos do
member do
match 'preview', to: 'photos#preview', via: :get
end
end
| Prefix | Verb | URIPattern | Controller#Action |
|---|---|---|---|
| preview_new_photo | GET | /photos/new/preview(.:format) | photos#preview |
| preview_photo | GET | /photos/:id/preview(.:format) | photos#preview |
| preview_photos | GET | /photos/preview(.:format) | photos#preview |
可以使用正则表达式或者一个可以响应matches?方法的对象来对参数进行约束
match 'account/setting/:id', constraints: {id: /[A-Z]\d{5}/}, to: 'account#setting', via: :get # 约束 /account/setting/A12345
match 'account/setting', constraints: { format: 'json' }, to: 'account#setting', via: :get # 这个不是太懂!
class Whitelist
def matches?(request) request.remote_ip == '1.2.3.4' end
end
match 'account/setting', to: 'account#setting', constraints: Whitelist.new, via: :get
| Prefix | Verb | URIPattern | Controller#Action |
|---|---|---|---|
| GET | /account/setting/:id(.:format) | account#setting {:id=>/[A-Z]\d{5}/} | |
| account_setting | GET | /account/setting(.:format) | account#setting {:format=>"json"} |
| preview_photos | GET | /account/setting(.:format) | account#setting |
设置默认params的值
match 'account/setting', to: 'account#setting', defaults: { id: 'hello' }, via: :get
params 输出:<ActionController::Parameters {"id"=>"hello", "controller"=>"account", "action"=>"setting"} permitted: false>
总结:以上我们学会了match方法的基础使用和它的一些选项,在往后的使用中更能得心应手。关于get, post, delete, put其实也是调用的match方法
感谢阅读,原文链接喜欢可以 star 哈