Ruby on Rails/路由
因為路由是 Rails 中非常重要的部分,所以我們專門為此分配了一整章(儘管它們是 ActionView 的一部分)。
例如,如果你想顯示 id 為 4 的產品,你將使用類似 products/4 的連結。這樣 Rails 就能識別出你想顯示 id 為 4 的產品資訊。
路由也適用於從應用程式中的一個點連結到另一個點。如果你想從產品檢視返回到顯示所有產品的索引概覽,你可以在檢視中放置類似以下內容:
<%= link_to 'Back', products_path %>
在編寫你自己的路由時,在routes.rb檔案中,請記住,路由在檔案中的位置越靠後,優先順序就越低。
RESTful 路由是 Rails 中的預設路由。要更詳細地瞭解 REST 的技術方面,請檢視 維基百科 文章。
基本上,REST 提供了一種在應用程式內部進行通訊的方式,以及所有來自外部來源(例如瀏覽器請求)的請求。為了更好地理解這些原則,請查看下錶。
| HTTP 動詞 | URL | 控制器 | 操作 | 用途 |
|---|---|---|---|---|
| GET | /products | Product | index | 在概覽中顯示所有產品 |
| GET | /products/new | Product | new | 返回用於建立新產品的 HTML 表單 |
| POST | /products | Product | create | 建立新產品 |
| GET | /products/1 | Product | show | 顯示特定產品 |
| GET | /products/1/edit | Product | edit | 返回用於編輯產品的 HTML 表單 |
| PUT | /products/1 | Product | update | 更新特定產品 |
| DELETE | /products/1/ | Product | destroy | 刪除特定產品 |
如你所見,所有 REST 操作已經在我們的腳手架控制器中。請記住,RESTful 路由引用單個物件(在本例中為 products)。這 7 個操作將在routes.rb:
map.resources :products
使用 RESTful 資源,可以輕鬆地將不同的檢視連結在一起,或連結到特定檢視。使用 REST,Rails 為我們提供了一些助手來訪問我們想要的位置。
- products_url & products_path => 重定向到產品索引概覽和編輯檢視(請注意複數形式)。
- new_product_url & new_product_path => 將引導使用者到用於建立新產品的表單。
- edit_product_url & edit_photo_path => 為特定產品提供編輯表單。
- product_url & product_path => 負責顯示、刪除和更新產品。
*_path 將建立一個相對路徑,而 *_url 將提供完整的 URL。
- _path => /products
- _url => https:///products
你很可能需要不止一個 REST 路由。可以輕鬆地將多個 REST 路由寫入單個
map.resources :products, :categories, :customers
你會遇到許多類似於我們的產品-類別關係的結構。
class Category < ActiveRecord::Base
has_many :products
end
class Product < ActiveRecord::Base
belongs_to :categories
end
| HTTP 動詞 | URL | 控制器 | 操作 | 用途 |
|---|---|---|---|---|
| GET | /products/1/categories | Category | index | 將顯示 id 為 1 的產品的類別概覽。 |
| GET | /products/1/categories/new | Category | new | 將提供一個 HTML 表單,用於為 id 為 1 的產品建立新類別。 |
| POST | /products/1/categories | Category | create | 將為 id 為 1 的產品建立新類別。 |
| GET | /products/1/categories/1 | Category | show | 將顯示屬於 id 為 1 的產品的 id 為 1 的類別。 |
| GET | /products/1/categories/1/edit | Category | edit | 將提供一個 HTML 表單,用於編輯屬於 id 為 1 的產品的 id 為 1 的類別。 |
| PUT | /products/1/categories/1 | Category | update | 更新屬於 id 為 1 的產品的 id 為 1 的類別。 |
| DELETE | /products/1/categories/1 | Category | destroy | 刪除屬於 id 為 1 的產品的 id 為 1 的類別。 |
與未巢狀的資源一樣,你可以訪問所有 *_url 和 *_path 助手,例如:products_categories_path或new_product_category_url
這些路徑需要出現在你的routes.rb中,與你的模型類似。
map.resources :products, :has_many => :categories
如果你需要新增多個關聯,請將它們放在 [] 中。
這與以下路由相同,只是更簡潔。
map.resources :magazines do |magazine|
magazine.resources :ads
end
透過這種方式,你可以巢狀任意多個資源,但應儘量保持巢狀級別儘可能低。因此,一個巢狀資源是可以的,但應避免兩個或多個。為了避免這些問題,我們可以使用“淺巢狀”。
如果我們要為特定類別新增供應商,最終可能會得到類似以下內容:
map.resources :publishers, :shallow => true do |publisher|
publisher.resources :magazines do |magazine|
magazine.resources :photos
end
end
或者簡寫為:
map.resources :products, :has_many => { :categories=> :suppliers }, :shallow => true
路由還有許多更高階的功能。更多資訊和說明可以在 官方 Rails 指南 中找到。
儘管鼓勵使用 RESTful 路由,但你也可以在應用程式中使用常規路由。使用常規路由時,你向 Rails 提供一些關鍵字,它將為你對映正確的路徑。其中一個預設路由已經在你的routes.rb(這次我們不使用.resources,而是使用.connect)
map.connect ':controller/:action/:id'
例如,將是一個類似於products/show/2
的瀏覽器請求。如果你熟悉其他以網路為中心的語言,你可能會想知道 URL 中的查詢字串是如何處理的:Rails 會自動將這些引數提供給 params 雜湊。
因此,如果你採用上面的示例並新增products/show/2?category=3,我們可以使用params[:category_id].