路由相关的类和模块在命名空间 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 哈