Rails 3 - 基于生成url的default_url_options

时间:2012-04-04 09:09:42

标签: ruby-on-rails ruby-on-rails-3 routing routes rails-routing

在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

1 个答案:

答案 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