Rails路由

資源路由

一行代碼完成資源資源路由聲明:html

resources :photos
複製代碼

這會建立7個不一樣的路由,這些路由會映射到 Photos 控制器上。正則表達式

這樣4個URL地址就會映射到7個不一樣的控制器動做上。json

用於生成路徑和URL地址的輔助方法

在建立資源路由時,會同時建立多個能夠在控制器中使用的輔助方法,如上面的資源路由會建立如下方法:數組

  • 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用於聲明公共路由,公共路由能夠在其餘資源和路由中重複使用:

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
複製代碼

從對象建立路徑和RUL地址

除了使用路由輔助方法,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
複製代碼

HTTP方法約束

經過使用 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 方法指明如何處理根路徑的請求:

root to: 'pages#main'
複製代碼

簡易寫法

root 'pages#main'
複製代碼

root路由只處理 GET 請求

unicode 字符路由

聲明路由時,能夠直接使用 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'
複製代碼

此時的具名輔助方法被修改成:

覆蓋 new 和 edit 片斷

: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
複製代碼

嵌套資源使用 :as 選項

這會覆蓋自動生成的輔助方法名稱:

resources :magazine do
    resources :ads, as: 'periodical_ads'
end
複製代碼

這會生成 magazine_periodical_ads_url 等輔助方法。

相關文章
相關標籤/搜索