我正在尝试了解路由/ 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存储为某个字符串?
答案 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被调用(这是我的情况)那么你需要重新考虑。由于“返回”条件是动态生成的,因此无法可靠地预测方法是返回默认路径还是尝试执行重写。
如果有人有更多信息要添加到此答案中,请进行修改。