2013-04-05 59 views
1

在我的Rails 3应用程序,我有一个包含我自己的助手一个模块,覆盖了几个建在轨助手:仅加载佣工

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(:包括ModuleB)是包含另一个模块中的一个模块的有效方式,但它不会做什么,我需要在这种情况下, :我的模块中的方法在视图中不可用。看起来好像Rails已经在任何控制器方法运行之前确定了哪些辅助方法可用于视图。

有没有办法做我需要的?

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

我认为这个问题的答案来自于理解轨道如何使视图可以访问辅助方法。

+0

为什么不干脆重新命名方法呢?他们显然做了别的事情,然后'form_for'和'link_to'在做。 – 2013-04-05 09:56:45

+0

因为我正在开发的库正在做一些应该在任何rails应用程序中与任何控制器一起工作的东西。控制器本身不应该知道发生了什么。 – cmrichards 2013-04-05 10:10:56

+1

我强烈建议不要覆盖原生Rails的帮助器方法。当'link_to'不工作时,会引发一些新的代码,就像Rails所说的那样。正如本杰明所说,我建议重新命名这些方法,并在必要时更新您的视图。 – osahyoun 2013-04-05 10:26:32

回答

0

由于Rails的自动加载,并包括在app/helpers目录中的所有助手,你可以尝试把你的助手在不同的位置,例如在lib目录。

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

+0

这正是我的客户Helper模块所在的位置,在lib文件夹中。问题不在于它被自动包含在内,问题是我只需要在某些请求中包含该模块。 – cmrichards 2013-04-05 10:18:44

+0

什么不起作用?你有错误信息吗?你在'config/application.rb'中正确配置了'autoload_paths'吗? – Vapire 2013-04-05 10:21:36

+0

没有错误消息,所以它似乎包含在ApplicationHelper模块中。问题是我的模块中的方法不可用于视图。 – cmrichards 2013-04-05 10:25:01

0

Vapire对将这些模块放置在app/helpers以外的地方有一个很好的观点。我会更进一步,说你想做什么可能不是明智的 - 有一些方法可用或不是每个动作的基础上感觉有点太脆弱,我喜欢。

我宁愿采取在你的控制器和ApplicationController之间放置定制控制器超类的方法,这些定制控制器超类包含模块(或者只是在你的超类中有这些方法)。

+0

这正是我的客户Helper模块存放在lib文件夹中的地方。问题不在于它被自动包含在内,问题是我只需要在某些请求中包含该模块。 – cmrichards 2013-04-05 10:25:33

+0

我建议你采取一种方法,这意味着你不仅仅包含某些请求的模块,而是包含针对不同控制器(和/或控制器超类)的模块。 – pat 2013-04-05 10:28:25

+0

是的,但我只需要它可以在几个不同的控制器之间传播的某些操作。我将使用配置文件来确定哪些操作(或url)应该受到影响。 – cmrichards 2013-04-05 10:31:44

-1

答案是使用“助手”类方法如下:

require "my_helpers" 
class MyController < ApplicationController 

    before_filter :add_helpers 

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

你真的需要'需要'my_helpers''吗?如果模块在你的'lib'目录下,这应该会自动发生... – Vapire 2013-04-05 11:12:45

+0

是的,你需要在rails 3中需要它(除非你添加一些自动加载路径)。在Rails 2中它是自动的,但现在你必须明确。 – cmrichards 2013-04-05 13:21:11

+0

这不是答案,因为'MyController.helper MyHelpers''导致助手永久加载控制器。它延迟加载助手,但一旦加载它可以通过任何其他操作调用。 – kuboon 2015-12-24 03:17:05

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 
0

config.action_controller.include_all_helpers应设置为false