一行代碼完成資源資源路由聲明:html
resources :photos
複製代碼
這會建立7個不一樣的路由,這些路由會映射到 Photos
控制器上。正則表達式
這樣4個URL地址就會映射到7個不一樣的控制器動做上。json
在建立資源路由時,會同時建立多個能夠在控制器中使用的輔助方法,如上面的資源路由會建立如下方法:數組
photos_path
:返回值爲 /photos瀏覽器
new_photos_path
:返回值爲 /photos/new緩存
edit_photo_path(:id)
:返回值爲 /photos/:id/edit安全
photo_path(:id)
:返回值爲 /photos/:idruby
這些方法都有對應的_url形式(photos_url),前者返回的是路徑,後者返回的是完整的url地址。bash
能夠同時定義多個資源路由:服務器
resources :photos, :books, :videos
複製代碼
等價於:
resources :photos
resources :books
resources :videos
複製代碼
使用 resource
方法能夠建立單數資源,這會建立6個不一樣的路由:
有時候在複數資源中但願可以不使用ID就能查找資源,如顯示當前登陸用戶的信息:
get 'profile', to: 'users#show'
複製代碼
若是 get
方法的to選項的值是字符串,那麼這個字符串應該使用controller#action形式,若是是表示動做的符號,則還須要添加controller選項:
get 'profile', to: :show, controller: 'users'
複製代碼
把控制器放入同一命名空間是很是常見的,如將管理員有關的控制器置於 Admin::
命名空間中,這樣能夠把控制器文件放在 app/controllers/admin
文件夾中,在路由中這樣聲明:
namespace :admin do
resources :articles, :comments
end
複製代碼
對於articles資源
若是想把 /articles 路徑(不帶/admin前綴)映射到Admin::Articles控制器上,能夠這樣聲明:
scope module: 'admin' do
resources :articles, :comments
end
複製代碼
或者
resources :articles, module: 'admin'
resources :articles, module: 'admin'
複製代碼
或者:
resources :articles, path: '/admin/articles'
複製代碼
有些資源是其餘資源的子資源,這種狀況很是常見:
class Magazine < ApplicationRecord
has_many :ads
end
class Ad < ApplicationRecord
belongs_to :magazine
end
複製代碼
經過嵌套路由來反映模型關聯:
resources :magazine do
resources :ads
end
複製代碼
對於嵌套路由,能夠不斷嵌套:
resources :publishers do
resources :magazine do
resources :photos
end
end
複製代碼
可是顯然嵌套太深是很是麻煩的,經驗告訴咱們嵌套資源層級不該該超過一層,而避免嵌套過深的方法之一就是把動做集合放在父資源中,這樣既能夠代表層級關係,又沒必要嵌套成員動做:
resources :articles do
resources :comments, only: [:index, :new, :create]
end
resources :comments, only: [:show, :edit, :update, :destroy]
複製代碼
固然,使用 :shallow
選項能夠簡化上面的代碼:
resources :articles do
resources :comments, shallow: true
end
複製代碼
固然,在複選項中使用 :shallow
選項,這樣會在全部的子資源中使用 :shallow
選項:
resources :articles, shallow: true do
resources :comments
resources :quotes
end
複製代碼
也可使用 shallow
方法建立做用域,使得全部嵌套均爲淺層嵌套:
shallow do
resources :articles do
resources :comments
resources :quotes
resources :drafts
end
end
複製代碼
使用scope方法也能夠來定義淺層路由,且有兩個選項,:shallow_path
選項會爲成員路徑添加前綴:
scope shallow_path: "sekret" do
resources :articles do
resources :comments, shallow: true
end
end
複製代碼
:shallow_prefix
選項會爲具名方法添加指定前綴:
scope shallow_prefix: "sekret" do
resources :articles do
resources :comments, shallow: true
end
end
複製代碼
路由concern用於聲明公共路由,公共路由能夠在其餘資源和路由中重複使用:
concern :commentable do
resources :comments
end
concern :image_attachable do
resources :images, only: :index
end
複製代碼
使用:
resources :messages, concerns: :commentable
resources :articles, concerns: [:commentable, :image_attachable]
複製代碼
至關於:
resources :messages do
resources :comments
end
resources :articles do
resources :comments
resources :images, only: :index
end
複製代碼
除了使用路由輔助方法,Rails還能夠從參數數組建立路徑和URL地址,假若有如下路由:
resources :magazine do
resources :ads
end
複製代碼
使用 magazine_ad_path
方法時,能夠傳入Magazine和Ad的實例,而不僅是數字ID:
<%= link_to 'Ad details', magazine_ad_path(@magazine, @ad) %>
複製代碼
還可使用 url_for
方法時傳入一組對象,Rails會自動肯定對應的路由:
<%= link_to 'Ad details', url_for([@magazine, @ad]) %>
複製代碼
Rails可以識別各個實例,自動使用 magazine_ad_path
輔助方法。固然在使用 link_to
等輔助方法時,能夠只指定對象,而沒必要完整調用 url_for
方法:
<%= link_to 'Ad details', [@magazine, @ad] %>
複製代碼
<%= link_to 'Magazine details', @magazine %>
複製代碼
若是想要連接到其餘控制器動做,只需把動做名稱做爲第一個元素插入對象數組便可:
<%= link_to 'Edit Ad', [:edit, @magazine, @ad] %>
複製代碼
這樣就可把模型實例看作URL地址,這是使用資源式風格最關鍵的優點之一。
和資源路由自動生成一系列路由不一樣,這時須要分別聲明各個路由,非資源路由能夠把任意URL地址映射到控制器動做的路由。
聲明普通路由時,可使用符號做爲參數:
get 'photos(/:id)', to: :display
複製代碼
在處理 /photos/1 請求時,會把請求映射到 Photos 控制器的 display 動做上,並把參數1傳入params[:id],並將路由映射到 PhotosController#display 上,而且 /photos 請求也會映射到這個控制器動做上,由於 :id 在括號中,是可選參數。
聲明普通路由時,容許使用多個動態片斷,動態片斷會傳入params,以便在控制器動做中使用:
get 'photos/:id/:user_id', to: 'photos#show'
複製代碼
/photos/1/2 請求會被映射到 photos#show 動做上,這時 params[:id] 的值是 1 ,params[:user_id] 的值是 2
params 也包含了查詢字符串中的全部參數,如:
get 'photos/:id', to: 'photos#show'
複製代碼
/photos/1?user_id=2 請求也會映射到 Photos#show 控制器動做上,這時params的值是
{controller: 'photos', action: 'show', id: '1', user_id: '2'}
複製代碼
:defaults
選項設定的散列爲路由定義默認值,未經過動態片斷定義的參數也能夠指定默認值
get 'photos/:id', to: 'photos#show', defaults: {format: 'jpg'}
複製代碼
Rails會把 /photos/12 路徑映射到 Photos#show 動做上,並把 params[:format] 設爲 'jpg'
固然 defaults 還有塊的形式,能夠爲多個路由定義默認值:
defaults format: :json do
resources :photos
end
複製代碼
固然須要注意的是查詢參數是不會覆蓋默認值的
可使用 :as
選項來爲路由命名
get 'exit', to: 'sessions#destroy', as: :logout
複製代碼
這個路由聲明會建立 logout_path 和 logout_url 這兩個具名輔助方法
路由命名能夠覆蓋資源路由定義的路由輔助方法:
get ':username', to: 'users#show', as: :user
複製代碼
經過使用 match 方法和 :via 選項,能夠一次匹配多個HTTP方法:
match 'photos', to: 'photos#show', via: [:get, :post]
複製代碼
經過 via: :all 選項,路由能夠匹配全部的HTTP方法
match 'photos', to: 'photos#show', via: :all
複製代碼
把GET和POST請求映射到同一個控制器動做上會帶來安全隱患,一般咱們應該避免將不一樣的HTTP方法映射到同一個控制器動做上。
使用 :contraints
選項能夠約束動態片斷的格式:
get 'photos/:id', to: 'photos#show', contraints: { id: /[A-Z]\d{5}/ }
複製代碼
這個路由會匹配 /photos/A12345 路徑,但不會匹配 /photos/893 路徑,這個還能夠簡寫爲:
get 'photos/:id', to: 'photos#show', id: /[A-Z]\d{5}/
複製代碼
:contraints 選項的值能夠是正則表達式,但不能使用 ^ 符號,好比下面就是錯誤的:
get '/:id', to: 'articles#show', constraints: { id: /^\d/ }
複製代碼
路由通配符用於指定特殊參數,這個參數會匹配路由的全部剩餘部分:
get 'photos/*other', to: 'photos#unknown'
複製代碼
這個路由會匹配 photos/12 和 /photos/long/path/to/12 路徑,並把 params[:other] 分別設置爲 "12" 和 "long/path/to/12"。像 *other 這樣以星號開頭的片斷,稱做「通配符片斷」。
通配符片斷能夠出如今路由中的任何位置:
get 'books/*section/:title', to: 'books#show'
複製代碼
在路由中可使用 redirect
輔助方法進行重定向
get '/stories', to: redirect('/articles')
複製代碼
重定向中也可使用源路徑的動態片斷:
get '/stories/:name', to: redirect('/articles/%{name}')
複製代碼
redirect 默認是301永久重定向,有些瀏覽器和代理服務器緩存這種類型的重定向,從而致使沒法訪問重定向前的網頁,爲了不這種狀況,咱們可使用 :status
選項修改響應狀態:
get '/stories/:name', to: redirect('/stories/%{name}'), status: 302
複製代碼
root 方法指明如何處理根路徑的請求:
root to: 'pages#main'
複製代碼
簡易寫法
root 'pages#main'
複製代碼
root路由只處理 GET 請求
聲明路由時,能夠直接使用 Unicode 字符:
get "忽如寄" , to: 'welcome#index'
複製代碼
:controller
選項用於顯式指定資源使用的控制器:
resources :photos, controller: 'images'
複製代碼
這時路由會把 /photos 路徑映射到 Images 控制器上
對於命名空間中的控制器,可使用目錄表示法:
resources :user_permissions, controller: 'admin/user_permissions'
複製代碼
:constraints
選項用於指定隱式 ID 必須知足格式要求
resources :photos, constraints: {id: /[A-Z][A-Z][0-9]+/ }
複製代碼
這時會約束 :id 參數,路由不會匹配 /photos/1 路徑,會匹配 /photos/PR12
固然也能夠同時約束多個路由:
constraints(id: /[A-Z][A-Z][0-9]+/) do
resources :photos
resources :accounts
end
複製代碼
resources :photos, as: 'images'
複製代碼
此時的具名輔助方法被修改成:
:path_names
選項用於覆蓋路徑中自動生成的 new 和 edit 片斷
resources :photos, path_names: { new: 'make', edit: 'change' }
複製代碼
這個路由可以識別如下路徑:
/photos/make
/photos/1/change
複製代碼
:path_names 選項不會改變控制器動做的名稱,仍然映射到 new 和 edit 動做上
Rails 默認會爲每一個 REST 式路由建立7個默認動做,可使用 :only
和 :except
選項來微調此行爲。 :only
選項用於指定想生成的路由:
resources :photos, only: [:index, :show]
複製代碼
:except
選項用於指定不想生成的路由:
resources :photos, except: :destroy
複製代碼
使用 scope
方法,能夠修改 resources 方法生成的路徑名稱:
scope(path_names: {new: 'neu', edit: 'bearbeiten'}) do
resources :categories, path: 'kategorien'
end
複製代碼
這會覆蓋自動生成的輔助方法名稱:
resources :magazine do
resources :ads, as: 'periodical_ads'
end
複製代碼
這會生成 magazine_periodical_ads_url
等輔助方法。