我需要从 Rails 应用程序中包含的模块访问 ActiveRecord 常量。
class User < ApplicationRecord
include ModOne
OPTIONS = {a: 1}.freeze
...
end
Module ModOne
extend ActiveSupport::Concern
included do
do_semething(self::OPTIONS)
end
class_methods do
def do_something(opts)
...
end
end
end
但我明白
NameError: 未初始化常量 User(调用“User.connection”建立连接)::OPTIONS 您是指?User::OPTIONS
我在这里遗漏了什么?
我也尝试过self
用base_class
和事件来替换User
但是出现了同样的错误。
这只是顺序问题。您必须先定义常量。Ruby 类实际上只是一个代码块,从上到下运行,当您调用时,
include
您也会调用#included
模块上的方法。但是,如果您希望模块提供的功能可定制,更好的方法是只编写所谓的宏方法,而不是将所有内容都挂在
Module#included
钩子上:这种模式在 Ruby 中随处可见,是解决
Module#include
不允许传递任何附加参数问题的好方法。在这个例子中,该
awesomeize
方法只是将选项存储为类实例变量。这种方法更受欢迎的一个最主要原因是它允许你为模块和其使用者之间的接口定义签名,而不是仅仅做出假设。一些像 Devise 这样的 gem 甚至使用这种方法来包含其子模块。