【问题标题】:How does Rails decide when to rewrite a URLRails 如何决定何时重写 URL
【发布时间】:2013-09-23 18:51:57
【问题描述】:

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

无论如何,rails 会为您的所有资源路径和资源 URL 格式的路径生成帮助器。

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

我正在尝试找出触发 UrlRewriter 的位置和方式? Rails 是否将“默认”无参数 url 作为字符串存储在某处?

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    对 _path 辅助方法进行逆向工程非常困难,因为其中大部分是动态生成的。该方法并不简单,这就是 :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 被调用的逻辑(这是我的情况),那么您需要重新考虑。由于“返回”条件是动态生成的,因此无法可靠地预测该方法是否会返回默认路径或尝试执行重写。

    如果有人有更多信息要添加到此答案中,请编辑。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-05
      • 2016-04-07
      • 2010-12-20
      • 2012-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-15
      相关资源
      最近更新 更多