0

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、上記の「シャーディング」は、キャッシングをオンにしたときに発生します。DB に多数の foo 行がある場合、1 つのフォルダー内のファイル数について、UNIX ベースのシステムの i ノード制限に達することになります。ある時点で。ここでの正しい「修正」は、おそらくキャッシュ設定を変更して、ルートを完全に分割するのではなく、分割されたパスにファイルを保存することです。ただし、上記のコードを書いている時点で、レールの外でキャッシュを提供する何かが必要になった場合に備えて、キャッシュされたファイルをルートと同じ構造に常に保持しておくとよいと感じた部分もありました。

しかし、悲しいかな、私はまだ上記の解決策に興味があります。それは、私がそれを理解できなかったことが私を食べているからです。

編集: 現在、他のすべての 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
4

1 に答える 1

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) %>

編集: または as をカスタマイズし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
于 2012-04-04T10:49:16.583 に答える