Rails如何决定何时重写URL

时间:2013-09-18 20:39:12

标签: ruby-on-rails ruby

我正在尝试了解路由/ URL编写机制的工作原理。我在Rails 2.3中,但Rails 3中的大多数模块都是相同的。

无论如何,rails为您的所有格式为resource_path和resource_url的路由生成帮助程序。

当您调用这些没有参数root_path()的帮助程序时,操作与使用额外参数root_path(:random_param=>"myquery")调用它们时的操作不同。当您将选项传递给_path帮助程序时,Rails会触发UrlRewriter#rewrite方法,并执行更全面的过程。

我正在尝试找出UrlRewriter触发器的位置和方式? rails实际上是否将'default'no-params url存储为某个字符串?

1 个答案:

答案 0 :(得分:0)

逆向工程_path辅助方法非常困难,因为它是动态生成的。这个方法并不简单,以下是对a:posts资源的说法和完成之后的样子。

def posts_path(*args)  
  users_url(*args)
   args.compact! 

    return "#{ActionController::Base.relative_url_root if ActionController::Base.relative_url_root}/posts" if 
             (!defined?(default_url_options) || default_url_options.blank?) && 
             (!defined?(controller.default_url_options) || controller.default_url_options.blank?) && 
             defined?(request) && request && args.size == 0

    return "#{ActionController::Base.relative_url_root if ActionController::Base.relative_url_root}/posts#{'?' + args.last.to_query unless args.last.empty?}" if 
          (!defined?(default_url_options) || default_url_options.blank?) && 
          (!defined?(controller.default_url_options) || controller.default_url_options.blank?) && 
          defined?(request) && request && args.size == 2 && !args.last.has_key?(:anchor) && 
          !args.last.has_key?(:params) && !args.last.has_key?(:only_path) && 
          !args.last.has_key?(:host) && !args.last.has_key?(:protocol) && !args.last.has_key?(:port) && 
          !args.last.has_key?(:trailing_slash) && !args.last.has_key?(:skip_relative_url_root) && !args.last.has_key?(:subdomain)

     opts = if args.empty? || Hash === args.first   
               args.first || {}                                                          
            else                                                                        
               options = args.extract_options!                                           
               args = args.zip([:format]).inject({}) do |h, (v, k)|  
                 h[k] = v                                                                
                 h                                                                       
               end                                                                       
               options.merge(args)                                                       
            end 

            url_for(hash_for_posts_path(opts))                         
          end 

路线模块积极尝试优化路线分辨率。 'return'语句是由rails或用户库/ gems动态构建的各种条件,用于解析路由而无需在最后通过url_for()方法。顺便说一句,这是ActionController#Base.url_for。

正如第一个'return'语句所示,如果args.size == 0,此方法将返回“/ posts”,这意味着在没有参数的情况下调用方法,即posts_path()。如果没有返回语句成功,则使用url_for启动UrlRewrite。

如果你有很多逻辑依赖于url_for被调用(这是我的情况)那么你需要重新考虑。由于“返回”条件是动态生成的,因此无法可靠地预测方法是返回默认路径还是尝试执行重写。

如果有人有更多信息要添加到此答案中,请进行修改。