打造Rails App(二) - Route + MVC目錄結構

Nathan Lee
Change or Die!
Published in
8 min readOct 13, 2017

Routes是公開的路徑對照表,共有4個部分供Rails使用及解析,包含了Prefix、Verb、URI Pattern 及 Controller#Action這4部分,如下圖,

routes

Rails會透過上述4個部分的內容進行解析,並依據解析結果判定由controller中的哪一個action負責執行後續動作。

舉個例,網址:https://nathan-photo-album.herokuapp.com/photos/2

假設config/routes.rb中只設定如下,

Rails.application.routes.draw do
get "photos/:id", to "photos#show"
end

Rails會依據/photos/2 去做判斷,對照routes對照表可以對應到Prefix: photo、Verb: GET、URI Pattern: /photos/:id(.:format) 及 Controller#Action: photos#show ,如下圖,

這背後的運作思維就是,當使用者瀏覽網址:https://nathan-photo-album.herokuapp.com/photos/2 時,Http request method(Verb)為GET,而存取路徑為/photos/2且參數(:id)為2,伺服器(Server)會將request指向PhotosController的show action及其方法。

RESTful 網址設計

什麼是REST? REST是Representational State Transfer,中文稱為具象狀態傳輸。它是由 Roy Thomas Fielding 博士在 2000 年時提出的全球資訊網軟體架構風格,目的是便於不同軟體/程式在網路(例如網際網路)中互相傳遞資訊。

REST的軟體架構風格,就是把每一個網址當做資源(Resource)供使用者使用,對同一個資源做不同的動作(HTTP Verb)會執行相對應的動作以及得到不同的結果。符合 REST 概念設計的網址,又稱之 RESTFul Route。

其中HTTP request method也就是HTTP Verb列舉如下,

  1. GET 擷取指定資源中資料
  2. PUT替換現有資源
  3. PATCH 更換資源部分內容
  4. DELETE 刪除指定資源
  5. OPTIONS 回傳該資源所支援的所有 HTTP request method
  6. CONNECT 將連線請求轉換到TCP/IP隧道
  7. POST 新增資源

所以我們現在知道,不同的Method就是對同一件事情做不同的操作。
再來舉服務生點餐的例子,
假設現在我們要點餐,我們必須先知道菜單是甚麼(get),
我們會向服務生點餐(post),
我們想要取消剛才點的餐點(delete),
我們想要重新點一次(put),
我們想要加點甜點和飲料(patch)。

到這裡我們已經提到了主要的Method了(head是取得get的http header而不取得內容,性質上我們可以當作跟get一樣),至於這幾種Method的行為我們可以統整一下:
head:和get一樣,只是head只會取的HTTP header的資料。
get:取得我們想要的資料。
post:新增一項資料。(如果存在會新增一個新的)
put:新增一項資料,如果存在就覆蓋過去。(還是只有一筆資料)。
patch:附加新的資料在已經存在的資料後面。(資料必須已經存在,patch會擴充這項資料)
delete:刪除資料。

引用自:常見的HTTP METHOD的不同性質分析:GET,POST和其他4種METHOD的差別

導入REST的網址設計,可以與Rails本身的慣例配合讓網址跟開發更直觀。

而Rails提供的resources method則可以便於開發者去符合RESTful的網址設計,我們只要在config/routes.rb輸入下方程式碼,

Rails.application.routes.draw do
resources :photos #resources method
end

再於terminal中使用$ rails routes 指令就能看到Rails自動產生的8個路徑及7個action,如下

resources :photos就讓 Rail自動產出 8 條不同的路由並且對應到 Controller 的 7 個method

而在 config/routes.rb 中我們還可以使用 root to: 來設定當使用者存取網站根目錄時的伺服器將會將 request 導向哪裡,如下

Rails.application.routes.draw do
resources :photos
root to: => 'photos#index'
end

Rails.application.routes.draw do
resources :photos
root "photos#index"
end

然後再於terminal中使用$ rails routes 指令就能看到最後Rails將存取路徑為 / 的「根目錄」指向index action,如下,

上述內容均提及了Verb、URI Pattern 及 Controller#Action在routes中的運做思維。

那Prefix是幹嘛的?

Prefix指的是在View的Helper命名,Prefix搭配 _path 會變成相對路徑;Prefix搭配_url則變成絕對路徑(絕對路徑,如:https://nathan-to-do-list.herokuapp.com/tasks ; 相對路徑,如: ./text.html)。

例如:

photos_path 產生/photos的路徑、new_photo_path 產生/photos/new的路徑、photo_path產生/photos/:id的路徑,會變成「產生相對路徑」的 View Helper。

new_photo_path的href

photos_url產生http://localhost:3000/photos 的路徑、new_photo_url 產生http://localhost:3000/photos/new 的路徑、photo_url產生http://localhost:3000/photos/:id 的路徑 等等的,會變成「產生完整的路徑,包含主機網域名稱的絕對路徑」的 View Helper。

new_photo_url的href

更多的Routes內容請參照:railsbook resources

Rails 專案 MVC目錄結構

在Terminal上開啟一個新的Rails專案後,Rails就會自動建立許多資料夾與檔案,便於團隊分工及開發,一種各司其職的概念。

/app

專案中絕大多數的程式碼都會在這裡,MVC的資料夾models、views、controllers也在這路徑下。

/bin

放Rails指令及script指令的資料夾。

/config

存放database、routes、environment等應用程式相關的設定檔。

/db

定義資料庫綱要 schema、資料庫遷移migration的資料夾。

/lib

存放自定義的檔案

/log

存放應用程式log記錄檔的地方

/public

唯一可以在網路上被看到的目錄,也是圖檔、JavaScript、和CSS和其他靜態檔案擺放的地方,也可以自己增加子目錄。如下圖中的/my-photo。

/test

存放測試程式。

/temp

暫存資料存放處。

/vender

用來放置第三方程式碼。

/Gemfile/Gemfile.lock

應用程式套件。

/rakefile

用來載入可以被命令列執行的一些 Rake 任務。

/README.md

在應用程式中最重要的檔案之一,因為這裡會紀錄著這個應用程式是做什麼用、該怎麼用等資訊

Reference: Alpha camp lighthouse

--

--