Как расширить url_for для предоставления динамических параметров по умолчанию

Я пытаюсь найти чистый и сухой способ расширения url_for, чтобы он предоставлял динамический параметр по умолчанию. Я знаю, это звучит странно, позвольте мне объяснить:

У меня есть набор вложенных маршрутов ресурсов, которые находятся под динамической областью:

scope "/:network", constraints: {:network => /[^\/]+/} do
  constraints DomainConstraint.new do
     resources :users do
       resources :posts
     end
  end
end

Это дает такие маршруты, как:

/mysite.com/users/mike
/someothersite.com/users/sally

Чтобы сгенерировать эти маршруты в представлении, я могу легко сделать:

mike = User.find_by_name("mike")
sally = User.find_by_name("sally")
user_path(mike.network, mike)
user_path(sally.network, sally)

Однако мне это не кажется очень СУХИМ, так как сеть фиксируется для каждого пользователя. Я бы предпочел кратко сказать:

user_path(mike)

person Peter P.    schedule 24.05.2013    source источник


Ответы (2)


Итак, я придумал решение, которое работает, но оно кажется очень хакерским, и мне интересно, есть ли более «правильный» способ сделать это:

module UrlForWithDefault
  def self.included(base)
    base.module_eval do
      alias_method_chain :url_for, :default
    end
  end
  def url_for_with_default(*args)
    if args[0].kind_of?(Hash)
      opts = args[0]
      if opts.has_key?(:_positional_keys) and opts[:_positional_keys].include?(:network)
        opts[:_positional_args].unshift(opts[:_positional_args][0].network)
        url_for_without_default(opts)
      end
    end
    url_for_without_default(*args)
  end
end
ActionDispatch::Routing::UrlFor.send(:include, UrlForWithDefault)

Мне не нравится этот подход, потому что он взламывает атрибуты «:_positional_keys» и «:_positional_args», которые потенциально могут измениться.

person Peter P.    schedule 24.05.2013
comment
выглядит хорошо, но вы должны использовать Module#prepend вместо alias_method_chain - person Mathieu J.; 09.12.2016

не могли бы url_options или Rails.application.routes.default_url_options сделать то, что вы хотите?

person Mathieu J.    schedule 19.06.2013
comment
нет, потому что тогда это не было бы одновременно динамическим и дефолтным, например динамически дефолтным... звучит противоречиво... но это не так :) - person Peter P.; 22.06.2013