仅在特定控制器操作上加载帮助程序

时间:2013-04-05 09:47:39

标签: ruby-on-rails ruby-on-rails-3

在我的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

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

有办法做我需要的吗?

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

我认为对此的答案来自于理解rails如何使视图可以访问辅助方法。

5 个答案:

答案 0 :(得分:1)

config.action_controller.include_all_helpers应设置为false

答案 1 :(得分:0)

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

这样.rb文件得到解析和加载,但模块不会自动包含在ApplicationHelper类中。然后你可以按照你所说的那样在你之前的过滤器中做到这一点。

答案 2 :(得分:0)

Vapire关于将这些模块放在除app/helpers以外的其他地方时有一个很好的观点。我会更进一步说出你想要做的事情可能并不明智 - 有一些方法可用或者没有基于一个动作感觉有点太脆弱了我的喜好。

我宁愿采用在您的控制器和ApplicationController之间安装包含模块的自定义控制器超类(或者只是在您的超类中使用这些方法)的方法。

答案 3 :(得分:0)

在控制器类或辅助类上添加帮助程序后,它将在请求后保持加载状态。 你需要在行动后卸载它们。 不幸的是,没有正式的方法可以卸载一部分助手,你需要编写它。

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

答案 4 :(得分:-1)

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

require "my_helpers"
class MyController < ApplicationController 

  before_filter :add_helpers

  def add_helpers
    if some_condition
      MyController.helper MyHelpers
    end
  end
  ..
end