Ruby on rails 在模块内创建全局Rails方法?
我需要创建一个可以在任何情况下使用的方法(MVC、测试等)。rbid希望创建一个模块并将其作为gem包含,而不是将其填充到Ruby on rails 在模块内创建全局Rails方法?,ruby-on-rails,ruby,Ruby On Rails,Ruby,我需要创建一个可以在任何情况下使用的方法(MVC、测试等)。rbid希望创建一个模块并将其作为gem包含,而不是将其填充到环境中。为了让Rails识别这个模块中的方法,我需要在gem中扩展什么类 更新: 我正在寻找一种解决方案,它允许我在不带模块前缀的情况下调用我的方法。TLDR 您需要通过使用include将您的方法包含到内核中来“扩展”内核模块 全局方法 通常,Ruby中的“全局”方法意味着在内核或对象中创建一个方法。然后,该方法可用于所有(大多数)类,因为它们继承自对象(包括内核)。大多数
环境中。为了让Rails识别这个模块中的方法,我需要在gem中扩展什么类
更新:
我正在寻找一种解决方案,它允许我在不带模块前缀的情况下调用我的方法。TLDR
您需要通过使用include
将您的方法包含到内核中来“扩展”内核模块
全局方法
通常,Ruby中的“全局”方法意味着在内核
或对象
中创建一个方法。然后,该方法可用于所有(大多数)类,因为它们继承自对象
(包括内核
)。大多数地方都可以在不使用前缀的情况下调用您的方法,因为任何给定上下文中的隐式self
将是继承自object
的对象,因此包含您定义的方法
定义此类方法的一种方法是将其定义放在任何类或模块之外的文件中:
def my_method
# do fancy stuff
end
当然,您必须确保在某个地方加载了该文件(即必需的)
来自模块的全局方法
如果希望在模块中组织方法(这是一个好主意),则需要将该模块包括到内核中,如下所示:
module MySpecialMethods
def my_method
# do fancy stuff
end
end
module Kernel
private
include MySpecialMethods # This is where the method gets added to Kernel
end
在Rails中,我将MySpecialMethods
模块放在lib/
中,添加Kernel
部分,将其放在初始化器文件中,如config/initializers/extend_Kernel.rb
。您还需要通过向application.rb添加config.autoload\u路径+=%W({config.root}/lib)
来帮助Rails在lib/
中“查找”您的模块
考虑避免全局方法
用这种方式扩展内核
是个好主意,这一点毫无价值。对于您的情况,最好将您的方法放在一个模块中,并使用模块名显式地调用它们,如MyModule.my_method
module MyModule
def self.my_method
# do fancy stuff here
end
end
您可以在许多地方放置此代码。在Rails中,我建议将其放在上面提到的lib/
文件夹中,然后通过向application.rb添加config.autoload\u路径+=%W(#{config.root}/lib)
来确保Rails可以找到它
来自宝石
创建gem超出了这个问题的范围,但是假设您创建了gem,只要您在gem文件中指定gem,该gem中的模块通常在Rails应用程序中可用。这是因为Rails应用程序默认调用Bundler.require
。只要gem遵循正确的命名约定,就会自动需要主gem文件,而主gem文件需要任何其他必要的文件
如果您想从gem扩展内核
,只需将内核
扩展代码(从上面)放在需要gem时(直接或间接)所需的文件中即可
笔记
Rails初始值设定项仅在引导Rails服务器时运行一次,因此对它们的更改不会像开发中的许多其他Rails一样自动加载
如果要调整Rails的自动加载路径
,可能还需要调整急切加载路径
(请参阅)
Ruby中有一些对象不是从对象继承的(例如),因此从技术上讲,这些“全局”方法并不适用于任何地方。这不太可能给你带来麻烦
在Rails应用程序中使用Bundler.require
可能会引起争议(有关更多信息,请参阅)
听起来你想要一个内核方法?例如,您可以将它放在lib/core\u ext/kernel.rb
中,并从config/boot.rb
中需要它。谢谢您的回复。因此,这是否允许我调用my_方法
,而无需为对象添加前缀(foo.my_方法
)?在我提供的示例中,您可以从代码中的任何地方将其称为MyModule.my_方法
,如测试、控制器、模型、视图等。我正在寻找一种解决方案,允许我调用my_方法
,而无需模块前缀。有什么想法吗?我已经更新了我的答案,因为我更好地理解了你的问题。我还更新了你的问题,以澄清你的意图。