Rails 在 1.2 版本的時候引進了 RESTful 這一套設計風格。而在 2.0 版強迫正式成為開發預設值。
說到 RESTful,幾乎每個剛踏進 Rails 框架中的開發者都皺起眉頭。幾乎沒有人能夠在初學階段搞的懂這是什麼玩意。偏偏初學者往往有一個「死扣細節」的壞習慣:沒「弄懂」就「不敢用」,結果在第一個關卡挫折感就堆的如山高,把玩 RESTful 後打退堂鼓,回頭大罵爛設計的人比比皆是。
想學 Rails 就先把 RESTful 背起來
RESTful 是 Rails 裡面使用的最基礎最頻繁的一個設計手法,偏偏它也是最難一次講解清楚讓剛入門者理解的一個主題。因為在傳統 web 應用程式開發流程中,根本沒有這樣的概念。更別提在市面上這麼多網頁框架,只有 Rails 將之視為預設值。
別說是初學者,就連筆者和一些 Rails 界的前輩,在 Rails 剛納入 RESTful 為預設風格時,也沒能通透其中原理。
但是不熟練 RESTful 的開發架構,在開發 Rails 時幾乎會寸步難行。在訓練新 Developer 時如何讓他短時間就熟練便上手呢?
我的方法很簡單:強迫他背起來,然後重複寫十遍。
聽起來很唬爛,但練過十遍以後。這時候再重新講解一次 RESTful 的概念,原本模糊的概念一下就變得豁然開朗了。
初步熟悉使用 Rails RESTful
在 config/routes.rb 內加入 resources
在 config/routes.rb 加入 resources :posts,就是具體在 rails 對一個 controller 實作 RESTful 的方式(對一個 controller 宣告成為 resources)。
1 2 3 | |
這樣的宣告將在自動對應 URL路徑跟 Controller 的 action ,而有以下的結果:
- GET: /posts => [:action => ‘index’]
- GET: /posts.xml => [:action => ‘index’, :format => ‘xml’]
- GET: /posts/1 => [:action => ‘show’, :id => 1]
- GET: /posts/1/edit => [:action => ‘edit’, :id => 1]
- GET: /posts/1.xml => [:action => ‘show’, :id => 1, :format => ‘xml’]
- POST: /posts => [:action => ‘create’]
- PUT: /posts/1 => [:action => ‘update’, :id => 1]
- DELETE: /posts/1 => [:action => ‘destroy’, :id => 1]
並產生了一套 url helpers 給 View 使用。
| helpers | HTTP Verb | 路徑 | Action |
|---|---|---|---|
| posts_path | GET | /posts |
index |
| post_path(id) | GET | /posts/1 |
show |
| new_post_path | GET | /posts/new |
new |
| posts_path | POST | /posts |
create |
| edit_post_path(id) | GET | /posts/1/edit |
edit |
| bloh_path(id) | PUT | /posts/1 |
update |
| post_path(id) | DELETE | /posts/1 |
destroy |
各 action 內部的動作以及對應 path
以下透過專案中使用 RESTful 應該會出現的程式碼作講解。讀者可以透過 rails generate scaffold Post subject:string content:text 看到這些程式碼。
index
通常會放置列表。因此 Post.all 是拉出 Post 這個 model 所有的資料。
1 2 3 | |
show
秀出單筆資料。 Post.find(123) 是指找 Post model 裡 id 為 123 的資料。http://demosite.com/posts/show/123 的 posts 是 controller、show 是 action;如果在 route 裡面沒有特別指定,則 123 通常就是 params[:id] 。
1 2 3 | |
new
initial 一個新的 Post object。
1 2 3 | |
edit
query 出指定的 Post model object,然後進行編輯。
1 2 3 | |
create
這邊要搭配 app/views/posts/new.html.erb 這個 view 並列一起看。
1 2 3 4 5 6 7 8 9 | |
1 2 3 4 5 6 7 8 9 10 11 | |
在 RESTful Rails 的寫法中,對 posts_path 丟 POST 就是對應到 create 的動作。而 Rails 在設計上,form 是綁 model 的,因此整個 form 的內容會被包成一個 hash,在這裡就是 params[:post]。create action 初始一個 object ,並把 params[:post] 整包塞進這個 object 裡。如果 @post 能夠成功的儲存,就「重導」到 index action ,失敗則「退回」到 new action 。
update
這邊也要翻回 app/views/posts/edit.html.erb 這個 view 一起來看。
1 2 3 4 5 6 7 8 9 | |
1 2 3 4 5 6 7 8 9 10 | |
在 RESTful Rails 的寫法中,對 post_path 丟 PUT 就是對應到 update 的動作。form 會背包成一個 hash,如果 @post 能夠吃進 params[:post] 進行更新且成功儲存,就會「重導」到 show action,失敗則「退回」到 edit action。
delete
找到該筆資料並刪除之。在 RESTful Rails 的寫法中,對 post_path 丟一個 DELETE,就會對應到 destroy 的動作。可看一下 link_to "Destroy"那一行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
還是不理解為什麼要這樣寫?沒關係,先練習十遍。練到不需要思考就能夠手寫這些程式碼再說。