给出一个班级
# foo.rb
class Foo
Rails.logger.info "Foo loaded"
end
位于#{Rails.root}/app/lib
。我在config/application.rb
添加了以下内容:
config.autoload_paths += %W(#{config.root}/app/lib)
当我通过rails s
或rails console
启动rails时,我希望看到Foo loaded
被记录。这是我打算做的简化版本,但它充分展示了我想要实现的目标。目前,发生的事情是在启动时没有记录任何内容。然后,当我明确地使用Foo时,例如使用Foo.new
,我会看到记录的消息。
Rails 3中最合适的方法是什么,以便在启动时看到记录的消息?
答案 0 :(得分:2)
这是我最终做的事情:
(1)在班级app/lib/foo.rb
中,我添加了一个静态方法来要求相应的文件
def self.load_foos
Dir["#{Rails.root}/app/lib/foos/*_foo.rb"].each do |file|
require file
end
end
(2)在foo.rb
中,我添加了一个静态方法,以便子类可以自己注册
def self.register
if @@subclasses.include?( self.registration_symbol )
raise FooExceptionSymbolAlreadyUsed, "symbol [#{self.registration_symbol}] is already in use."
end
@@subclasses[self.registration_symbol] = [self.registration_priority,self]
end
(3)我在app/lib/foos
创建了一个目录,在那里我放了foo的各个子类,并将它们命名为this_foo.rb
和that_foo.rb
。
(4)在子类app/lib/foos/this_foo.rb
中,我添加了以下内容
class Foos::ThisFoo < Foo
def self.registration_symbol
:this
end
def self.registration_priority
100
end
# other methods removed to make example easier to read
register
end
(5)我添加了config/initializers/load_foos.rb
,其中只有
Foo::load_foos
我放入app/lib/foos/
且名称正确的Foo的任何子类将在启动时自动加载。每个子类都覆盖并实现registration_symbol
和registration_priority
的方法(优先级稍后用于对枚举进行排序),并且该符号用于create方法。
因此,我可以向我的开发人员发布一个规范,向他们展示在子类中实现哪些Foo方法以及如何注册它以及保存它的位置,然后Rails应用程序将在下次启动时自动加载这些文件。
答案 1 :(得分:0)
我有类似的情况 - 我的模型中有一大堆常量,当Rails启动时,实际上只需要加载一次,但每次访问该模型时似乎都会重新加载。我解决了它如下:
如果您正在处理常量(例如Foo::PI = 42
),这应该适合您。如果你要定义方法......也许吧?在Rails重新加载已更改的类时,您可能会在开发模式中遇到一些问题 - 我不确定。
希望这有帮助!
答案 2 :(得分:0)
Rails开发环境虽然很适合开发,但对于加载和需求来说有点奇怪。
但是,如果您使用标准的Ruby要求,您会发现更可预测的事情。我建议您使用导轨config.autoload_paths
对于您想要始终需要的代码,只需在config / application.rb的最后添加require 'app/lib/foo'
,在模块定义之外。
此外,通常lib位于rails目录的根目录,而不是app文件夹中。这是一种类型还是有意识的选择?