跳转到内容

Ruby on Rails/路由

来自维基教科书,开放的书籍,为开放的世界

因为路由是 Rails 中非常重要的部分,所以我们专门为此分配了一整章(尽管它们是 ActionView 的一部分)。

例如,如果你想显示 id 为 4 的产品,你将使用类似 products/4 的链接。这样 Rails 就能识别出你想显示 id 为 4 的产品信息。

路由也适用于从应用程序中的一个点链接到另一个点。如果你想从产品视图返回到显示所有产品的索引概览,你可以在视图中放置类似以下内容:

 <%= link_to 'Back', products_path %>

在编写你自己的路由时,在routes.rb文件中,请记住,路由在文件中的位置越靠后,优先级就越低。

理解路由

[编辑 | 编辑源代码]

RESTful 路由

[编辑 | 编辑源代码]

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。


你很可能需要不止一个 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_pathnew_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].

访问类别 ID。

参见

[1]

华夏公益教科书