rails URL路由

   rails URL路由的最權威文檔當然是其官方站點Rails routing from the outside in,我這裏只提幾個文檔中常用的要點。

1.CRUB

   由resources建立的資源,是rails中最常見的路由方式,不用多說。
resources :photos

2.單例資源

   單例資源也比較常用,官方文檔上舉的例子很形象也很常見,用戶user需要擁有一個profile資源,而每個用戶必然只有一個profile,所以如果生成類似/profiles/:id的URL顯然是不美觀的,此時就需要單例資源,單例資源的生成使用的是單數形式方法resource:
resource :profile

   該語句生成的路由如下:


3.嵌入的路由

    適用於某種資源必須依賴於另一種資源纔有意義,比如某些comment必然在針對的event下存在,所以comment就必須依賴於event。
resources :events do
    resources :comments
end


    對應的也自動生成了諸如event_comment_path之類的url 幫助方法。對於嵌入式資源,官方建議不要超過兩層。最簡單的理由,路由層次過深,除了增加邏輯的複雜度外,也得不到任何好處。

4.namespace和scope路由

    以下規則同時適用於resources和controller。
    比如,如果想要在特定的命名空間(admin)下訪問某個資源(post),這時就可以利用namespace。
namespace :admin do
  resources :posts
end

    此時,處理該路由的controller是Admin::PostsController,體現在rails工程中是在controller文件夾下的admin文件夾下的posts_controller.rb文件。而產生的路由全部以/admin開頭:

    一言以蔽之,由namespace產生的資源路由,controller和url都由該namespace作“前綴”。
    如果需要讓資源路由沒有前綴,而又希望該路由url被某個模塊下的controller受理,那麼就需要使用scope。
scope module: 'admin' do
  resources :posts
end
 
    由rake routes輸出可以看出,路由url沒有了admin前綴,而posts資源都由admin模塊下的Admin::PostsController受理。
    一言以蔽之,帶module的scope產生的資源路由,路由url無“前綴”,controller以module指定模塊爲“前綴”。
   反過來,如果希望給資源附加一個前綴,而由普通controller受理該url,則需要另一種形式的scope:
scope '/admin' do
  resources :posts
end


    此時,資源posts每個url都附加了/admin爲前綴,而受理這些url的是PostsController。
    一言以蔽之,這種形式的scope產生的資源路由,路由url有“前綴”,controller無“前綴”。
    另外,這種形式的路由還有一種簡寫:
resources :posts, path: '/admin/posts'

   該簡寫和使用scope產生的結果完全一樣。不過,path還有另外的用途,如果保持controller及url helper不變,僅僅希望爲url路由中的資源改個名稱,這時path就派上用場了:
resources :posts, path: '/articles'



5.新增RESTful動詞

    以下規則同樣適用於resources和controller。
resources :photos do
  get 'preview', on: :member
end

    該語句爲某個特定photo新增了一個preview動作,該動作是一個get請求,默認photos_controller中存在一個preview方法處理該動作。
    類似的,如果需要爲photos集合新增一個動詞,只需要將語句中member改成collection即可。
    如果,需要爲特定photo增加多個動詞preview1和preview2,改成下面的形式即可,甚至可以指定controller中處理該請求的方法,以及自定義url helper:
resources :photos do
  member do
    get 'preview1'=>:pre1, as:"p1"
    get 'preview2'=>:pre2, as:"p2"
  end
end



6.非resourceful路由

使用參數:

controller :photos do
  get 'check/:id',:to=>:check
end

   產生的路由輸出如下:
GET /check/:id(.:format) photos#check

    在執行該get請求如/check/23,後photos_controller的check方法受理該請求,並在params中將參數設置爲23。

限制參數格式:

get 'photos/:id', to: 'photos#show', constraints: { id: /[A-Z]\d{5}/ }

    該路由規則能接受/photos/A12345卻不能接受/photos/893。

指定請求的默認類型:

    
get 'articles/:id', to: 'articles#show', defaults: { format: 'xml' }
    若get請求/articles/2,該路由規則會自動將params的params[:format]置爲"xml"。
    該方法僅僅是在請求未指定format時指定默認類型,如果需要某個controller僅接受某些格式的請求如xml和json,則可以在該controller類定義中添加如下代碼,這在書寫api時常常用到:
respond_to :json, :xml

更換資源的controller:

   如果不希望爲某個資源使用默認的controller,則:
resources :photos, controller: 'images'

   此時photos資源的所有請求都由images_controller受理,而photos的路由url和url helper都不變。

限制資源的默認動作:

   如果僅希望使用資源的部分動作,如僅使用資源photos的index和show動作:
resources :photos, only: [:index, :show]

   或者使用除了destroy動作外的所有默認動作:
resources :photos, except: :destroy
     還可以使用:all(所有默認動作),:none(沒有默認動作):
resources :photos, :only=>:none


爲new和edit的url路由改名:

resources :photos, path_names: { new: 'make', edit: 'change' }

   產生的新路由爲:
/photos/make
/photos/1/change

   而此時受理該路由的方法仍爲new和edit,即controller中的方法並未改名。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章