Ruby on rails 使用define_方法重写Rails中的路径帮助程序

Ruby on rails 使用define_方法重写Rails中的路径帮助程序,ruby-on-rails,ruby,Ruby On Rails,Ruby,我需要重写RubyonRails中的许多path helper方法,并从中调用super。我的标准方法是: path\u helper.rb def business_path(business) if params[:city_id] == 2 moscow_business_path(business) else super end end 但是我有很多这样的方法,所以我想动态地定义它们,如下所示: %i[root businesses business .

我需要重写RubyonRails中的许多path helper方法,并从中调用super。我的标准方法是:
path\u helper.rb

def business_path(business)
  if params[:city_id] == 2
    moscow_business_path(business)
  else
    super
  end
end
但是我有很多这样的方法,所以我想动态地定义它们,如下所示:

  %i[root businesses business ...].each do |path_method|
    method_name = "#{path_method}_path"
    old_method = method(method_name)
    define_method(method_name) do |*args|
      if params[:city_id] == 2
        public_send("moscow_#{method_name}")
      else
        old_method.call(*args)
      end
    end
  end
但我得到了这个错误:

 /home/leemour/Ruby/burobiz/app/helpers/path_helper.rb:31:in `method': undefined method `root_path' for class `Module' (NameError) 
 from /home/leemour/Ruby/burobiz/app/helpers/path_helper.rb:31:in `block in <module:PathHelper>'
 from /home/leemour/Ruby/burobiz/app/helpers/path_helper.rb:29:in `each' 
 from /home/leemour/Ruby/burobiz/app/helpers/path_helper.rb:29:in `<module:PathHelper>' 
 from /home/leemour/Ruby/burobiz/app/helpers/path_helper.rb:1:in `<top (required)>' 
 from /home/leemour/.rbenv/versions/2.3.3/lib/ruby/gems/2.3.0/gems/activesupport-5.1.3/lib/active_support/dependencies.rb:476:in `load'
/home/leemour/Ruby/burobiz/app/helpers/path\u helper.rb:31:in'method':类'Module'的未定义方法'root\u path'(NameError)
from/home/leemour/Ruby/burobiz/app/helpers/path_helper.rb:31:in'block in'
from/home/leemour/Ruby/burobiz/app/helpers/path_helper.rb:29:in'each'
from/home/leemour/Ruby/burobiz/app/helpers/path\u helper.rb:29:in`'
from/home/leemour/Ruby/burobiz/app/helpers/path\u helper.rb:1:in`'
来自/home/leemour/.rbenv/versions/2.3.3/lib/ruby/gems/2.3.0/gems/activesupport-5.1.3/lib/active\u support/dependencies.rb:476:在“加载”中

我想助手模块还没有包括在内,所以没有原始的路径助手方法可以用
方法(method\u name)
捕获。然后我想我必须使用
self.included
hook,但我想不出来。如何调整此代码以使其正常工作?(我不想使用eval)。

您是否尝试过使用
Rails.application.routes.url\u helpers
方法,而不是尝试使用
Kernel.method

%i[...].each do |path_method|
  define_method("#{path_method}_path") do |*args|
    if params[:city_id] == 2
      public_send("moscow_#{path_method}_path", *args)
    else
      Rails.application.routes.url_helpers.public_send("#{path_method}_path", *arsg)
    end
  end
end

你也可以把所有的电话都打包

def path_name_for(path_name,*args) 
  path = "#{path_name}_path"
  path.prepend("moscow_") if params[:city] == 2
  public_send(path,*args)
end 
那么在你看来,只需打电话

<%= link_to 'Business Path', path_name_for(:business, @business) %>

我在整个项目中都有路径助手,所以更换它们不是一个理想的选择solution@leemour很好,我在其他条件相同的情况下添加了一个新的实现,这也是我将采用的方法。干净多了。谢谢,这样行得通。但是,我还想知道在包含模块后如何定义方法,因此我有一个通用的解决方案,而不是使用
url\u helpers
进行黑客攻击。你能帮忙吗?使用UrthHelpor也使用<代码> PuxyPase<代码>。¯\_(ツ)_/“'url_helpers的使用在控制器上下文之外是很常见的(比如模型或类似的东西)。@leemour:我自己没有尝试过,但我有一个好的感觉,如果你用monkeypatch来修补url helpers对象(在初始值设定项或类似的东西中),您将实现您想要的。同时也发送参数,因为它们现在正在被删除,所以
business\u path(@business)
之类的操作将失败。请查看:。尤其是“方法包装”部分。
module PathHelper
  module MoscowRedirect
    def self.prepended(base) 
      %i[...].each do |path_name|
        define_method("#{path_name}_path") do |*args|
          params[:city] == 2 ? public_send("moscow_#{__method__}",*args) : super(*args)
        end
      end
    end
  end
  self.prepend(MoscowRedirect)
end