Router的两个作用:
- 把网址路径和代码连接起来;
- 通过代码生成路径和网址;
简单的一行 resources :product
可以自动匹配CRUD中的所有操作(logdown表格支持好像有问题)
HTTP Verb | Path | Controller#Action | Helpers |
---|---|---|---|
GET | /products | products#index | products_path |
GET | /products/new | products#new | new_product_path |
POST | /products | products#create | products_path |
GET | /products/:id | products#show | product_path(:id) |
GET | /products/:id/edit | products#edit | edit_product_path(:id) |
PATCH/PUT | /products/:id | products#update | product_path(:id) |
DELETE | /products/:id | products#destroy | product_path(:id) |
这其中复杂的是各种嵌套和新的关键字使用
普通的单层嵌套只是在上表基础上多一层关系admin/products
,这种关系逻辑清晰易懂:
namespace :admin do
resources :products
end
但是到多层关系时就很容易出现头痛的问题
resources :publishers do
resources :magazines do
resources :photos
end
end
这个routes产生的路径会是这样/publishers/1/magazines/2/photos/3
,对应的helper也会显得复杂publisher_magazine_photo_url
。所以官方建议是:
资源嵌套应该以不超过一层为佳(Resources should never be nested more than 1 level deep)。相关文章
这一点在以后路径的自定义过程中需要注意。
更多的RESTful Action(member,collection,new)
1.添加 Member Routes
resources :products do
member do
post :add_to_cart
end
end
这样系统会通过POST
识别/products/1/add_to_cart
,接着会路由到ProductsController中对应的action(add_to_cart),并且会用传进params[:id]
中的id值查看相应的界面。Rails同时也会创建add_to_cart_product_url
和add_to_cart_product_path
helpers。例如:
<%= link_to("加入购物车", add_to_cart_product_path(@product),
method: :post,
class: "btn btn-primary btn-lg btn-danger") %>
在member代码块中的每个HTTP verb(GET, PATCH, PUT, POST, DELETE)都会被识别,我们可以同时添加多个action,例如在招聘网站中用到的显示和隐藏工作用到的routes:
namespace :admin do
resources :jobs do
member do
post :publish
post :hide
end
end
end
单个member的routes可以简写成
resources :products do
post :add_to_cart, on: :member
end
2.添加 Collection Routes
resources :carts do
collection do
delete :clean
end
end
一键清空购物车时用到的routes。Rails会通过DELETE识别/carts/clean,同时会通过CartsController路由到clean动作。和member一样同样也会创建clean_carts_url
和clean_carts_path
helpers
<%= link_to("清空购物车", clean_carts_path,
method: :delete, class: "pull-right",
style: "text-decoration: underline;",
data: {confirm: "确定清空购物车?"}) %>
class CartsController < ApplicationController
def clean
current_cart.clean!
flash[:warning] = "购物车已经清空"
redirect_to carts_path
end
end
models/cart.rb
class Cart < ApplicationRecord
def clean!
cart_items.destroy_all
end
end
简写模式同member routes
3.为Routes添加额外的 New Actions(课程中未涉及)
resources :products do
get 'search', on: :new
end
Rails会通过GET动作识别像/products/new/search
的路径,并会路由到ProductsController
中对应的action。同时rails也会创建search_new_product_url
和 search_new_product_path
helpers
小结:
在routes.rb中添加member,collection或者new相当于开了一条新的线路,新增加的线路必须在对应的控制器中定义对应的方法来匹配生成的路径。
member vs collection
member 生成的helpers是这样add_to_cart_product_path
collection 生成的helpers是这样clean_carts_path
单数和复数形式不同很直白了,member是针对个体行为的操作(添加某个商品到购物车),collection是批量操作(一键清空购物车)。