只在特定的控制器动作上加载帮助程序



在我的Rails 3应用程序中,我有一个包含我自己的帮助程序的模块,它覆盖了几个内置的Rails帮助程序:

module MyHelpers
  def form_for(*args)
     ...
  end
  def link_to(*args)
     ...
  end
end

上面的模块位于lib文件夹中。

我希望这些助手只用于特定的控制器动作。我的第一个尝试是这样的:

require "my_helpers"
class MyController < ApplicationController 
  before_filter :add_helpers
  def add_helpers
    if some_condition
      ApplicationHelper.send(:include, MyHelpers)
    end
  end
  ..
end

模块。send(:include, ModuleB)是在另一个模块中包含一个模块的有效方法,但它不做我在这种情况下需要的:我的模块中的方法在视图中不可用。似乎Rails已经在运行任何控制器方法之前确定了视图可以使用哪些帮助器方法。

有办法做我需要的吗?

我知道我可以全局覆盖form_for方法,但我宁愿不这样做。

我认为这个问题的答案将来自于理解rails如何使视图访问helper方法。

config.action_controller。Include_all_helpers应该设置为false

由于Rails自动加载并包含app/helpers目录中的所有帮助程序,因此您可以尝试将帮助程序放在不同的位置,例如在lib目录中。

这样,.rb文件被解析和加载,但模块不会自动包含在ApplicationHelper类中。然后你可以像你说的那样在before过滤器中做

Vapire关于将这些模块放置在app/helpers以外的地方有一个很好的观点。我想更进一步说,你想做的可能是不明智的——在每个动作的基础上提供一些可用的方法或不提供一些方法对我来说有点太脆弱了。

我宁愿采取自定义控制器超类坐在你的控制器和ApplicationController之间的方法,包括模块(或只是有这些方法在你的超类)。

一旦在控制器类或helper类上添加了helper,它将在请求后保持加载状态。你需要在行动后卸下它们。不幸的是,没有正式的方法来卸载一部分帮助程序,你需要自己写。

class MyController < ApplicationController
  around_action :load_helper, only: :create
  def load_helper
    self.class.helper_method :your_helper_method
    yield
    self.class.helper { undef your_helper_method }
  end
end

答案是使用'helper'类方法如下:

require "my_helpers"
class MyController < ApplicationController 
  before_filter :add_helpers
  def add_helpers
    if some_condition
      MyController.helper MyHelpers
    end
  end
  ..
end

最新更新