Rails Routing, member及collection研究

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_urladd_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_urlclean_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_urlsearch_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是批量操作(一键清空购物车)。


参考资料:Rails Routing from the Outside In

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Awesome Ruby Toolbox Awesome A collection of awesome Ruby...
    debbbbie阅读 2,935评论 0 3
  • 自己做dede的开发时间也比较长了,基本上常用的函数都知道在哪个文件里面,但是时间一长,也有点模糊了,俗话说:好记...
    大刘的英语世界阅读 1,754评论 1 9
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,080评论 19 139
  • 那天, 我高三请假回家看你, 中午你我谈话, 你紧握我的手, 问我何时高考, 我说到时候我会告诉你, 你等着吧。 ...
    繁尘若星阅读 801评论 1 4
  • 这是村上春树令人怀念的1980年代中的一个小故事。一个男的,40多岁,和一个20多岁的女的在一起了。之后女的想分手...
    简小宇_xy阅读 198评论 0 0