Ruby on rails 使用define_方法重写Rails中的路径帮助程序
我需要重写RubyonRails中的许多path helper方法,并从中调用super。我的标准方法是: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 .
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