在 rails 3 中,是否可以访问在 default_url_options() 内部生成的 URL 的控制器/操作?在 rails 2 中,您收到了即将被传递给 url_for() 的选项的哈希值,您当然可以更改这些选项。
例如 Rails 2 代码:
==== config/routes.rb
map.foo '/foo/:shard/:id', :controller => 'foo', :action => 'show'
==== app/controllers/application.rb
def default_url_options options = {}
options = super(options)
if options[:controller] == 'some_controller' and options[:id]
options[:shard] = options[:id].to_s[0..2]
end
options
end
==== anywhere
foo_path(:id => 12345) # => /foo/12/12345
但是,在 rails 3 中,由于 default_url_options 没有传递任何选项哈希,相同的代码失败了,我还没有弄清楚如何测试控制器是什么。
FWIW,上述“分片”是由于当您打开缓存时,如果您的数据库中有大量 foo 行,那么您将在基于 unix 的系统上达到 inode 限制,以获取 1 个文件夹中的文件数在某一点。此处正确的“修复”可能是更改缓存设置以将文件存储在分片路径中,而不是完全分片路由。不过,在编写上述代码时,我的一部分感觉总是将缓存文件与路由保持在相同的结构中是很好的,以防万一您想要使用 rails 之外的东西来服务缓存。
但是,唉,我仍然对上述解决方案感兴趣,纯粹是因为它在吞噬我,我无法弄清楚。
编辑:目前我有以下我必须放弃的,因为你失去了所有其他 named_route 功能。
==== config/routes.rb
match 'foo/:shard/:id' => 'foo#show', :as => 'original_foo'
==== app/controllers/application.rb
helpers :foo_path
def foo_path *args
opts = args.first if opts.is_a?(Array)
args = opts.merge(:shard => opts[:id].to_s[0..2]) if opts.is_a?(Hash) and opts[:id]
original_foo_path(args)
end