在rails 3中,是否可以访问default_url_options()内部生成的URL的控制器/操作?在rails 2中,你传递了一个Hash,这些选项将被传递给url_for(),你当然可以改变它。
E.g。 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
答案 0 :(得分:0)
定义一个像
这样的帮手# app/helpers/foo_helper.rb
module FooHelper
def link_to name, options = {}, &block
options[:shard] = options[:id].to_s[0..1] if options[:id]
super name, options, &block
end
end
然后在你的视图中执行以下操作,似乎对我有用
<%= link_to("my shard", id: 12345) %>
修改:或将foo_path
自定义为
module FooHelper
def link_to name, options = {}, &block
options[:shard] = options[:id].to_s[0..1] if options[:id]
super name, options, &block
end
def foo_path options = {}
options[:shard] = options[:id].to_s[0..1] if options[:id]
super options
end
end