Rails自定义类静态init

时间:2011-03-25 00:26:48

标签: ruby ruby-on-rails-3 initialization

给出一个班级

# 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 srails console启动rails时,我希望看到Foo loaded被记录。这是我打算做的简化版本,但它充分展示了我想要实现的目标。目前,发生的事情是在启动时没有记录任何内容。然后,当我明确地使用Foo时,例如使用Foo.new,我会看到记录的消息。

Rails 3中最合适的方法是什么,以便在启动时看到记录的消息?

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.rbthat_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_symbolregistration_priority的方法(优先级稍后用于对枚举进行排序),并且该符号用于create方法。

因此,我可以向我的开发人员发布一个规范,向他们展示在子类中实现哪些Foo方法以及如何注册它以及保存它的位置,然后Rails应用程序将在下次启动时自动加载这些文件。

答案 1 :(得分:0)

我有类似的情况 - 我的模型中有一大堆常量,当Rails启动时,实际上只需要加载一次,但每次访问该模型时似乎都会重新加载。我解决了它如下:

  1. 我在config / initiaizers文件中定义了常量(启动时自动加载的文件)
  2. 我向访问这些常量的模型添加了方法
  3. 如果您正在处理常量(例如Foo::PI = 42),这应该适合您。如果你要定义方法......也许吧?在Rails重新加载已更改的类时,您可能会在开发模式中遇到一些问题 - 我不确定。

    希望这有帮助!

答案 2 :(得分:0)

Rails开发环境虽然很适合开发,但对于加载和需求来说有点奇怪。

但是,如果您使用标准的Ruby要求,您会发现更可预测的事情。我建议您使用导轨config.autoload_paths

尽可能多地离开

对于您想要始终需要的代码,只需在config / application.rb的最后添加require 'app/lib/foo',在模块定义之外。

此外,通常lib位于rails目录的根目录,而不是app文件夹中。这是一种类型还是有意识的选择?