我有一个模块包含一些" class"或者" DSL"目前的方法如下:
module Things
module ClassMethods
def thing id, title, **options
# ... create and register a thing ...
end
# ... more DSL methods ...
end
extend ClassMethods
# define project things
thing :ruby, "Ruby programming language"
thing :rails, "Ruby on Rails web framework"
thing :active_support, "ActiveSupport library"
end
所以我在ClassMethods
中定义了DSL方法,用Things
扩展ClassMethods
然后在模块体中使用DSL。我已经按照约定选择了名称ClassMethods
,虽然模块不是主动记录关注,但我看到了轨道。
现在我想将DSL定义与其用法分开,因此我将代码分成
lib/things/class_methods.rb
:
module Things
module ClassMethods
def thing id, title, **options
# ... create and register a thing ...
end
# ... more DSL methods ...
end
end
和lib/things.rb
:
require_relative "things/class_methods"
module Things
extend ClassMethods
# define project things
thing :ruby, "Ruby programming language"
thing :rails, "Ruby on Rails web framework"
thing :active_support, "ActiveSupport library"
end
但是在这个问题出现之后:代码在重新启动rails服务器后第一次按预期工作,但后续使用此模块的请求会引发模糊错误或抱怨DSL方法没有定义或以其他方式表现得好像DSL呼叫没有做他们应该做的事情。感觉好像extend ClassMethods
行选择了错误的模块ClassMethod
,但后来我不明白为什么我最初工作。
知道我的方法究竟出了什么问题,以及解决这个问题的最佳解决方案是什么?我应该重命名DSL模块,以便它不会与框架中其他地方定义的ClassMethods
发生冲突吗?或者我还能做些什么来继续使用名称ClassMethods
而不会发生冲突?
答案 0 :(得分:1)
Rails有时会在autoloading and reloading期间失去对常量的跟踪,需要一些帮助。
这可以是显式依赖:
# lib/things.rb
require_dependency 'things/class_methods' # <- tells Rails that we depend on this
require_relative 'things/class_methods'
module Things
extend ClassMethods
# ...
end
或者使用完全合格的内容:
# lib/things.rb
require_relative 'things/class_methods'
module Things
extend ::Things::ClassMethods
# ...
end
使用extend Things::ClassMethods
可能就足够了,前提是您没有在Things
下嵌套另一个Things
模块。
哪种方法有效,似乎取决于您的类结构和自动加载配置。
答案 1 :(得分:0)
您是否尝试使用/lib
方法将application.rb
目录添加到.autoload_paths
文件中?