REST(表述性状态转移,Representational State Transfer) 架构的应用程序将一个URL视作一个资源,使用 HTTP 的 GET, POST, PUT, DELETE 方法来访问,创建,更新和删除资源。 Rails 将 REST 组织成更适合 Web 应用程序的形式, 使得构建路由和 URL 变得异常简单。
首先在 routes.rb 中添加一个资源路由
# config/routes.rb
resources :products
使用 rake routes 可以方便的查看所生成的路由和对应的方法
products GET /products(.:format) products#index
POST /products(.:format) products#create
new_product GET /products/new(.:format) products#new
edit_product GET /products/:id/edit(.:format) products#edit
product GET /products/:id(.:format) products#show
PUT /products/:id(.:format) products#update
DELETE /products/:id(.:format) products#destroy
如果控制器的名称为单数, 那么资源集合的路由相应的变为 controller_index
product_index GET /product(.:format) product#index
POST /product(.:format) product#create
每个方法对应一个资源,因此一个 resources 路由总共产生4个资源: 产品的集合,单个产品,添加产品时的表单,编辑产品时的表单。 其中后两者属于用户界面, 负责将用户信息提交到 create 和 update 这两个动作,在一些只提供API的应用程序中不是必须的,可以在定义路由的时禁用它们。
resources :products, :except => [:new, :edit]
创建新产品是向 "/products" 发送 POST 请求,这个动作可以理解为向集合添加新的资源,因为需要创建的资源还不存在,只能指明将它添加到哪里。
在视图和控制器中,资源路由生成的4个方法名加上 url 或 path 后缀的方法可以用于构建资源的 URL地址 或 路径。
products_url
# => http://0.0.0.0:3000/products
products_path
# => /products
对于单个的资源,Rails 通过资源 id 来构建 URL,因此需要传递 id 或 资源的实例(包含了id属性)做为参数
product_path(1)
# => /products/1
product_path(:id => 1)
# => /products/1
@product = Porduct.find(1)
product_path(@product)
# => /products/1
更进一步,在 Rails 中以 url 为参数的方法都可以接受一个实例变量作为参数来构建 url
<%= link_to "Show", @product %>
这些方法同时还可以接受一个指定HTTP请求动作的参数
<%= link_to "Show", @product, :method => :delete %>
<!-- app/views/products/new.html.erb -->
<%= form_for(@product, :url => products_url do |f| %>
...
<% end %>
<!-- app/views/products/eidt.html.erb -->
<%= form_for(@product, :url => products_url(@post), :html => { :method => "put"}) do |f| %>
...
<% end %>
由于创建新资源时返回的资源实例总是没有 id 的,因此上面的两个表单方法还可以进一部简化为
<%= form_for(@product) do |f| %>
...
<% end %>
Rails 会根据资源是否为新建的来自动生成表单提交的地址和HTTP动作,最终使得编辑和创建资源时的表单调用奇妙的保持一致。