对 _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 被调用的逻辑(这是我的情况),那么您需要重新考虑。因为“返回”条件是动态生成的,所以无法可靠地预测该方法是否会返回默认路径或尝试执行重写。
如果有人有更多信息要添加到此答案中,请编辑。