iT邦幫忙

0

collection / member in Ruby 村

在修改專案的時候碰上了,
所以就想說順便記錄一下,讓自己下次忘記時還能回來翻
因為主要是想講這兩個方法究竟能做什麼,所以前面敘述會比較簡單一些。

首先因為 Rails 導入 Restful 網址的設計理念,主要可以讓網址變得更直觀、易讀,
我們可以使用 Rails 內建的resources方法來快速創造出我們所需要的路徑

Rails.application.routes.draw do
  resources :rackets
end

那這到底會產生些什麼路徑呢?我們啟動終端機到專案底下執行rails routes

Prefix | Verb | URI Pattern | Controller#Action
------------- | -------------
rackets | GET | /rackets(.:format) | rackets#index
| POST | /rackets(.:format) | rackets#create
new_racket | GET | /rackets/new(.:format) | rackets#new
edit_racket | GET | /rackets/:id(.:format) | rackets#edit
racket | GET | /rackets/:id(.:format) | rackets#show
| PATCH | /rackets/:id(.:format) | rackets#update
| PUT | /rackets/:id(.:format) | rackets#update
| DELETE | /rackets/:id(.:format) | rackets#destroy

這就把上面做的路徑全部顯示出來了,就是resources方法辦到的
額外補充一下最前面Prefix還有個特殊的魔法:
就是在這些字的後方如果加上_path會得到站內的網址;
而加上_url則會得到完整的網址。
舉例來說:

rackets_path => # /rackets
new_racket_path => # /rackets/new
edit_racket_path(5) => # /rackets/5/edit  

rackets_url => # http://example.com/rackets
new_racket_url => # http://example.com/rackets/new
edit_racket_url(5) => # http://example.com/rackets/5/edit  

講了這麼多,也許有人會說

可是我好像不需要這麼多路徑,這麼多看得我眼花撩亂

那我們可以配合onlyexcept來達到我們的需求

Rails.application.routes.draw do
  resources :rackets, only: [:index, :show]
end

# 這樣就會得到我們想要的兩條路徑
# 那如果相反的我們除了這兩條路徑以外都需要

Rails.application.routes.draw do
  resources :rackets, except: [:index, :show]
end

# 這樣就會得到剩下6條路徑啦~

我們在實作的時候,可能又有這樣的想法出現

難道我只能使用內建的這些路徑嗎?

這才要開始進入我們今天要介紹的兩位主角collection/member
其實兩種方法都能為我們增加路徑,至於差別在哪裡,讓我們繼續看下去~

我們想要設計一個情境:如果我想要檢視已售出(sold)的球拍

Rails.application.routes.draw do 
  resources :rackets do
    collection do
      get :sold
    end 
  end
end

我們來看一下這樣會產生什麼?
Prefix | Verb | URI Pattern | Controller#Action
------------- | -------------
sold_rackets | GET | /rackets/sold | rackets#sold
rackets | GET | /rackets(.:format) | rackets#index
| POST | /rackets(.:format) | rackets#create
new_racket | GET | /rackets/new(.:format) | rackets#new
edit_racket | GET | /rackets/:id(.:format) | rackets#edit
racket | GET | /rackets/:id(.:format) | rackets#show
| PATCH | /rackets/:id(.:format) | rackets#update
| PUT | /rackets/:id(.:format) | rackets#update
| DELETE | /rackets/:id(.:format) | rackets#destroy

/rackets/sold 確實就是我們預期想檢視的網址
並且在 controller 中也幫我們指向了 rackets#sold
除了 do...end 這樣的寫法外,下面的寫法也可以得到相同的效果~

Rails.application.routes.draw do 
  resources :rackets do
    get :sold, on: :collection
  end
end

再來我們看一下 member 的部分
我們一樣先來設定一下情境:我想刪除2號拍子!

Rails.application.routes.draw do 
  resources :rackets do
    member do
      delete :cancel
    end 
  end
end

再輸入rails routes 看看會出現什麼結果?
Prefix | Verb | URI Pattern | Controller#Action
------------- | -------------
cancel_racket | DELETE | /rackets/:id/cancel(.:format) | rackets#cancel
rackets | GET | /rackets(.:format) | rackets#index
| POST | /rackets(.:format) | rackets#create
new_racket | GET | /rackets/new(.:format) | rackets#new
edit_racket | GET | /rackets/:id(.:format) | rackets#edit
racket | GET | /rackets/:id(.:format) | rackets#show
| PATCH | /rackets/:id(.:format) | rackets#update
| PUT | /rackets/:id(.:format) | rackets#update
| DELETE | /rackets/:id(.:format) | rackets#destroy

原來collectionmember差在產生的路徑中,會有:id
這個:id會成為 controller 中params的一部份。
同樣的不想用 do...end 的寫法,也可以這樣寫得到相同的結果。

Rails.application.routes.draw do
  resources :rackets do
    delete :cancel, on: :member
  end
end

以上內容皆參考於高見龍,龍哥的書籍
如果需要更詳細的內容,歡迎前往為你自己學 Ruby on Rails
希望分享會對你有幫助~


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言