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://127.0.0.1/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].