2011-03-25 61 views
1

提供类Rails的自定义类的静态初始化

# 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,我想看看Foo loaded被记录。这是我打算做的简化版本,但它足以证明我正在努力实现的目标。目前,发生的情况是在启动时没有记录任何内容。然后,当我明确使用Foo时,例如使用Foo.new,我会看到记录的消息。

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

回答

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/和名称正确,将在启动时自动加载。每个子类重写和实现registration_symbolregistration_priority(优先级稍后用于对枚举进行排序)的方法,并且该符号用于create方法。因此,我可以向我的开发者发布一个spec,告诉他们Foo在子类中实现哪些方法,以及如何注册它以及在哪里保存它,然后Rails应用程序会在下一次启动时自动加载这些文件。

0

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

  1. 我定义的常量在一个文件中的config/initiaizers(文件有在启动时自动加载)
  2. 我添加的方法我的模型,访问这些常量

如果你正在处理常量(例如Foo::PI = 42),这应该适合你。如果你正在定义方法...也许?您可能会遇到一些开发模式的问题,当Rails重新加载已更改的类时 - 我不确定。

希望这会有所帮助!

+1

我正在寻找使用方法。 'config/initializers'是我一直在考虑的方法之一。只是想看看这是否是解决这个问题的适当方式,或者是否有不同/更好的东西。感谢你的回答。 – sorens 2011-03-25 01:16:19

0

Rails开发环境虽然对于开发来说非常棒,但对于加载和需求有点奇怪。

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

对于你想要的代码,只需在config/application.rb的最后加上一个require 'app/lib/foo',在模块定义之外。

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

+1

是的,在'Rails.root'中有一个lib目录。在我的示例中''lib /'可以很容易地被'squishy_banana_gold /'除了'lib /'键入更快。感谢你的回答。 – sorens 2011-03-25 01:53:06

+0

这两种方法都适合你吗? – 2011-03-27 12:20:56