Ruby on rails Routes是什麼?

Routes的角色

簡單來說,Routes就像是服務台一樣,讓所有來拜訪的使用者指引方向
我拿華泰名品城做為比喻,華泰名品城這麼大的園區,有一期二期三期園區
走一走很容易迷路

這時候就需要服務台幫忙,櫃台會依據使用者的需求,詢問對應的部門,美食餐飲部、電影娛樂部、顧客服務部、精品部等等

找到部門之後,請部門提供相關的資料
Routes會導覽到某Controller,Controller的action幫你做事情;只要任一個沒有對應的話,會出現HTTP 404錯誤的訊息

MVC

圖片來源
The Ping Relationship of Model, View, and Controller(MVC)

之前文章講到 RESTful-API設計風格

HTTP方法 路徑 Controller Action 說明
GET /articles ArticleController index 文章列表
POST /articles ArticleController create 新增文章
GET /articles/new ArticleController new 新增文章的頁面
GET /articles/:id/edit ArticleController edit 編輯文章的頁面
GET /articles/:id ArticleController show 檢視單一文章
PATCH /articles/:id ArticleController update 更新單一文章
PUT /articles/:id ArticleController update 更新單一文章
DELETE /articles/:id ArticleController destroy 刪除單一文章

CRUD

CRUD是一個縮寫,代表著「Create」、「Read」、「Update」和「Delete」。這些動作通常是針對某個特定資源所作出的行為,例如建立資料、讀取資料、更新資料和刪除資料。而且在使用SQL資料庫和網站的API時也很常見。

以下是一些CRUD的例子:

  • 建立(Create) 在一個資料庫中新增一筆資料,例如建立一篇新的文章。
  • 讀取(Read) 從一個資料庫中讀取資料,例如讀取一篇文章。
  • 更新(Update) :在一個資料庫中更新資料,例如更新一篇文章。
  • 刪除(Delete) :在一個資料庫中刪除資料,例如刪除一篇文章。

Ruby on rails
會根據config/routes.rb檔案的內容,找到對應的Controller裡面的Action

to: 後面接的是Controller名稱 以及 #Action名稱

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Rails.application.routes.draw do

<!-- 建立文章列表 -->
get '/articles', to: 'articles#index'

<!-- 新增文章的頁面(一個頁面可以填寫文章的資料,等於是一份表單可以填寫資料) -->
get '/articles/new', to: 'articles#new', as: 'new_article'

<!-- 真正做新增,按下按鈕發送新增的動作 -->
post '/articles', to: 'articles#create'


<!-- Routes有先後順序之分,次序愈前面,優先啟用,優先讀取 -->
<!-- show, edit, update, delete 藉由尋找id來對應文章,這些需要放在new路徑之後 -->

<!-- 建立每一篇文章呈現的頁面,另外as:可以自己定義名稱,就可以在view的地方,使用article_path來引用這個路徑,不擔心'/articles/:id'之後被怎麼修改。 -->
get '/articles/:id', to: 'articles#show', as: 'article'

<!-- 編輯文章的頁面(一份表單可以填寫資料,但不是新增) -->
get '/articles/:id/edit', to: 'articles#edit' , as: 'edit_article'

<!-- 更新文章資料,按下按鈕發送更新的動作 -->
patch '/articles/:id', to: 'articles#update'

<!-- 刪除文章資料,按下按鈕發送刪除的動作 -->
delete '/articles/:id', to: 'articles#destroy'

end

首頁的Routes怎麼寫呢?

假設要把articles#index作為網站的首頁
有以下2種,通常選第1種,因為字面上更直覺

1
2
3
4
5
6
7
8
9
Rails.application.routes.draw do

<!-- 第1種 -->
root 'articles#index'

<!-- 第2種 -->
get '/', to: 'articles#index'

end

快速建立路由,resources

另外Ruby on rails提供更快的方法建立Routes,使用 resources

首頁還是要自己設定喔,因為rails不知道你要哪一頁當作首頁

譬如以下,可以生成剛剛那一堆Routes(7個Action),節省很多時間

1
2
3
4
5
6
Rails.application.routes.draw do

root 'articles#index'
resources :articles

end

如果不小心寫成單數resource ?!

resource :articles

  • 生成的路徑都不會帶上:id(show, edit, update, delete沒有id)
  • 不會有index頁面

Routes巢狀設計

假如希望每一篇文章底下都可以留言,Routes可以這樣寫

1
2
3
4
5
6
7
Rails.application.routes.draw do

resources :articles do
resources :comments
end

end

每一篇文章會有自己的流水編號(id),而且不會重複
每一則留言也會有自己的流水編號(id),而且不會重複

可是留言的部分,只需要部分的Action,我只要開特定幾個路徑

留言不需要index,從文章的show頁面借來使用
留言需要新增,也就是create
留言不需要new,從文章的show頁面借來使用
留言不需要show功能
留言不開放edit功能
留言不開放update功能
留言需要刪除,也就是destroy;刪除的路徑不用綁在articles後面,根據留言的id,直接刪除即可

所以可以這樣改寫,符合我要的需求

1
2
3
4
5
6
7
8
9
Rails.application.routes.draw do

resources :articles do
resources :comments, only: [:create]
end

resources :comments, only: [:destroy]

end

另外,也可以使用except: [:action, :action, :action],意思是除了這些的action以外,其他的路徑才開啟
中括號裡面action名稱要記得修改

更多路徑選項(collection, member)

現在訂單order使用resources產生路徑

1
2
3
4
5
Rails.application.routes.draw do

resources :orders

end

然後我想要增加路徑是用來檢視已經取消的訂單
使用collection,/orders,針對全部資源

1
2
3
4
5
6
7
8
9
Rails.application.routes.draw do

resources :orders do
collection do
get :cancelled
end
end

end

HTTP方法是GET
路徑是/orders/cancelled
Action是cancelled

那如果是取消第2號訂單 ,路徑要怎麼設計呢?
使用member,路徑會帶上id,/orders/:id/,針對單一資源

1
2
3
4
5
6
7
8
9
Rails.application.routes.draw do

resources :orders do
member do
delete :cancel
end
end

end

HTTP方法是DELETE
路徑是/orders/:id/cancel
Action是cancel

同一個Controller裡面的Action名稱不能重複,找不到對應的動作,會出現錯誤

參考資料
為你自己學Ruby on Rails