Rails每周一题(二): routes

本文解析了Rails中的路由配置,包括默认规则、无名规则、具名规则、REST风格路由及嵌套规则等,同时介绍了如何使用rake命令查看路由映射。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Rails其实很好懂,可视的源码和大量的注释,只看你有没有心去一窥究竟。今天就来看看貌似神秘的routes吧。

一个命令

首先,介绍一个rake命令。对于不了解routes定义规则的,或许看到routes.rb文件有点迷糊。不要紧,如果你想看看一个url到底对应了哪个controller以及action,就用rake routes展开所有的奥秘吧。

几多规则

routes的定义规则其实不多,让我们来一一分析下吧。不过要保持耐心。

分析routes.rb文件,首先得搞清楚,它的优先级是从上到下,谁先匹配谁先得。

1. 默认规则

 

  # Install the default routes as the lowest priority.
  # Note: These default routes make all actions in every controller accessible via GET requests. You should
  # consider removing the them or commenting them out if you're using named routes and resources.
  map.connect ':controller/:action/:id'
  map.connect ':controller/:action/:id.:format'

 

  自定义的路由规则往往需要覆盖默认的路由规则,所以,rails的routes模板把默认路由规则放在文件的最下面,并且鼓励考虑用具名路由替换它们。

2. 无名规则

  大家看到前面的map.connect,那么这个方法到底做了什么?

  # Create an unnamed route with the provided +path+ and +options+. See
  # ActionController::Routing for an introduction to routes.
  def connect(path, options = {})
     @set.add_route(path, options)
  end

 

  可以看到,connect方法为我们生成了一个无名路由规则。

  我们可以如此生成一个无名规则:

map.connect 'products/:id', :controller => 'catalog', :action => 'view'


3. 具名规则
 
  为什么要有具名规则,主要是因为rails可以为具名规则生成一些url helper。关于routes的helper,待会儿再详细描述,先来看看具名规则吧。

 

map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'


  如此,我们已经生成了一个名字叫做purchase的具名规则。
 
  看看源代码

def named_route(name, path, options = {}) #:nodoc:
    @set.add_named_route(name, path, options)
end


4. 单资源REST风格路由规则: map.resource

   我们定义这样一个规则: map.resource :account

 

   它会帮我们定义怎样的一个路由规则呢? 答案是一个遵循REST风格的路由规则,非常完美。

 

  # maps these actions in the Accounts controller:
  class AccountsController < ActionController::Base
      # GET new_account_url
       def new
         # return an HTML form for describing the new account
      end
    
      # POST account_url
      def create
        # create an account
      end
   
      # GET account_url
      def show
        # find and return the account
      end
    
     # GET edit_account_url
      def edit
        # return an HTML form for editing the account
      end
   
      # PUT account_url
      def update
        # find and update the account
      end
    
     # DELETE account_url
      def destroy
        # delete the account
      end
   end
 

    让我们用rake routes看看它为我们生成了怎样的路由。

 

    account POST                                     /account                            {:controller=>"accounts", :action=>"create"}
    formatted_account POST                 /account.:format               {:controller=>"accounts", :action=>"create"}
    new_account GET                             /account/new                    {:controller=>"accounts", :action=>"new"}
    formatted_new_account GET         /account/new.:format       {:controller=>"accounts", :action=>"new"}
    edit_account GET                             /account/edit                     {:controller=>"accounts", :action=>"edit"}
    formatted_edit_account GET          /account/edit.:format        {:controller=>"accounts", :action=>"edit"}
    GET                                                     /account                              {:controller=>"accounts", :action=>"show"}
    GET                                                     /account.:format                 {:controller=>"accounts", :action=>"show"}
    PUT                                                     /account                               {:controller=>"accounts", :action=>"update"}
    PUT                                                      /account.:format                 {:controller=>"accounts", :action=>"update"}
    DELETE                                             /account                               {:controller=>"accounts", :action=>"destroy"}
    DELETE                                             /account.:format                 {:controller=>"accounts", :action=>"destroy"}
      

5. 集合资源REST风格路由规则

 

    我们定义一个这样的规则: map.resources :messages

 

   #   map.resources :messages
 
    # will map the following actions in the corresponding controller:
      class MessagesController < ActionController::Base
       # GET messages_url
       def index
         # return all messages
       end
    
      # GET new_message_url
       def new
         # return an HTML form for describing a new message
       end
    
       # POST messages_url
       def create
         # create a new message
       end
   
     # GET message_url(:id => 1)
       def show
         # find and return a specific message
       end
   
     # GET edit_message_url(:id => 1)
       def edit
         # return an HTML form for editing a specific message
       end
   
       # PUT message_url(:id => 1)
       def update
         # find and update a specific message
       end
    
       # DELETE message_url(:id => 1)
       def destroy
         # delete a specific message
       end
     end

 

     messages GET                          /messages                                {:controller=>"messages", :action=>"index"}
     formatted_messages GET       /messages.:format                   {:controller=>"messages", :action=>"index"}
     POST                                           /messages                                {:controller=>"messages", :action=>"create"}
     POST                                           /messages.:format                   {:controller=>"messages", :action=>"create"}
     new_user GET                           /messages/new                       {:controller=>"messages", :action=>"new"}
     formatted_new_user GET       /messages/new.:format          {:controller=>"messages", :action=>"new"}
     edit_user GET                             /messages/:id/edit                  {:controller=>"messages", :action=>"edit"}
     formatted_edit_user GET        /messages/:id/edit.:format      {:controller=>"messages", :action=>"edit"}
     user GET                                      /messages/:id                          {:controller=>"messages", :action=>"show"}
     formatted_user GET                   /messages/:id.:format             {:controller=>"messages", :action=>"show"}
      PUT                                              /messages/:id                           {:controller=>"messages", :action=>"update"}
      PUT                                             /messages/:id.:format              {:controller=>"messages", :action=>"update"}
     DELETE                                        /messages/:id                          {:controller=>"messages", :action=>"destroy"}
      DELETE                                     /messages/:id.:format            {:controller=>"messages", :action=>"destroy"}



6. 嵌套规则

 

    简单嵌套规则

 

map.resources :products, :has_many => [ :comments, :sales ], :has_one => :seller
 

    用rake routes看看生成的路由规则,即可一目了然。


     一个更加复杂的嵌套规则

 

map.resources :products do |products|
    products.resources :comments
    products.resources :sales, :collection => { :recent => :get }
end
 

7. root

# You can have the root of your site routed with map.root -- just remember to delete public/index.html.
map.root :controller => 'home'  
 

     root路由用于映射根目录。

8. namespace

 

     我们还可以定义一个命名空间,如这样。

 

 

map.namespace :admin do |admin|
    # Directs /admin/products/* to Admin::ProductsController (app/controllers/admin/products_controller.rb)
   admin.resources :products
end

 

7. path_prefix, name_prefix等其他options

 

    当想让不同的method访问同一个url时,对应到不同的controller或者action,可以如是:

 

 

map.signup '/signup', :controller => 'people', :action => 'new', :conditions => {:method => :get}
map.signup '/signup', :controller => 'people', :action => 'create', :conditions => {:method => :post}
 

    还是不再赘述了,这样的option很多,在不明白的时候,不如直接看源代码吧。
 

routes helpers

 

    当我们定义了一个具名路由或者REST风格路由时,router helper会为我们生成一些帮助方法。

 

    比如当我们定义了一个这样的路由时:

 

map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'

 

     生成的helper方法有:

 

     purchase_url(:id => 1)  #  http://test.url/products/1/purchase

     purchase_path(:id => 1)  #  /products/1/purchase

     hash_for_purchase_url(:id => 1)   # {:controller=>"sessions", :action=>"new", :use_route=>:new_session, :only_path=>false}

     hash_for_purchase_path(:id => 1)  # {:controller=>"sessions", :action=>"new", :use_route=>:new_session, :only_path=>true}

 

delete & put

 

     对delete和put method,现在大多数浏览器都不能处理,所以以post方法代替,并附上:method参数。

 

 

<% form_for :message, @message, :url => message_path(@message), :html => {:method => :put} do |f| %>  
 

保持简单

 

     最后有点感触,随着项目的进行,routes会变得越来越复杂,越来越难以看懂。所以,我们要遵循保持简单,尽量使用REST风格的原则。

内容概要:本文档详细介绍了Analog Devices公司生产的AD8436真均方根-直流(RMS-to-DC)转换器的技术细节及其应用场景。AD8436由三个独立模块构成:轨到轨FET输入放大器、高动态范围均方根计算内核和精密轨到轨输出放大器。该器件不仅体积小巧、功耗低,而且具有广泛的输入电压范围和快速响应特性。文档涵盖了AD8436的工作原理、配置选项、外部组件选择(如电容)、增益调节、单电源供电、电流互感器配置、接地故障检测、三相电源监测等方面的内容。此外,还特别强调了PCB设计注意事项和误差源分析,旨在帮助工程师更好地理解和应用这款高性能的RMS-DC转换器。 适合人群:从事模拟电路设计的专业工程师和技术人员,尤其是那些需要精确测量交流电信号均方根值的应用开发者。 使用场景及目标:①用于工业自动化、医疗设备、电力监控等领域,实现对交流电压或电流的精准测量;②适用于手持式数字万用表及其他便携式仪器仪表,提供高效的单电源解决方案;③在电流互感器配置中,用于检测微小的电流变化,保障电气安全;④应用于三相电力系统监控,优化建立时间和转换精度。 其他说明:为了确保最佳性能,文档推荐使用高质量的电容器件,并给出了详细的PCB布局指导。同时提醒用户关注电介质吸收和泄漏电流等因素对测量准确性的影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值