强制rails自动加载类

时间:2012-04-07 19:50:42

标签: ruby-on-rails ruby autoload

我在/ app / models中的单个文件中有几个小类,类似于:

# /app/models/little_class.rb
class LittleClass; ...do stuff; end;
class AnotherLittleClass; ...do stuff; end;

Rails似乎只适用于反映类名的文件中的自动加载类。因此,在文件之外引用AnotherLittleClass会引发“unitialized constant”错误,如下所示,直到LittleClass被引用为止:

irb(main):001:0> AnotherLittleClass 
NameError: uninitialized constant AnotherLittleClass
irb(main):02:0> LittleClass
=> LittleClass
irb(main):03:0> AnotherLittleClass
=> LittleClass2

将它们分成单个文件会很麻烦。有没有办法自动加载这些类,所以引用没有LittleClass的AnotherLittleClass不会引发错误?

4 个答案:

答案 0 :(得分:4)

您可以将它们放入模块中并在此命名空间SomeLittleClasses::LittleClass.do_something

中使用它们
# /app/models/some_little_classes.rb
module SomeLittleClasses

  class LittleClass
    def self.do_something
      "Hello World!"
    end
  end

  class AnotherLittleClass
    def self.do_something
      "Hello World!"
    end
  end

end

答案 1 :(得分:1)

尝试这个技巧:

1.9.2p312 :001 > AnotherLittleClass.new
# => NameError: uninitialized constant AnotherLittleClass
1.9.2p312 :002 > autoload :AnotherLittleClass, File.dirname(__FILE__) + "/app/models/little_class.rb"
# => nil 
1.9.2p312 :003 > AnotherLittleClass.new
# => #<AnotherLittleClass:0xa687d24> 

答案 2 :(得分:1)

正如我所看到的,这些是你的选择:

  1. 将每个类的文件拆分为一个文件,将它们放在根据rails约定命名的目录(SomeClass =&gt; some_class.rb)和启动文件中(例如,在config/initializers)中创建一个文件,调用:

    autoload_paths Rails.application.config.root + "/path/to/lib"
    
  2. 将这样的内容添加到启动文件中:

    %W[
        Class1 Class2
        Class3 Class4 Class4
    ].map(&:to_sym).each dp |klass|
        autoload klass,Rails.application.config.root + "/path/to/lib/file"
    end
    

    每次将新课程添加到文件时,都必须更新。

  3. 将所有类移动到模块/类命名空间中,并调用autoload将其添加为上面

  4. 只需将整个文件预先加载到require的启动文件中。问问自己:额外的努力是否需要延迟此文件的负载?

答案 3 :(得分:0)

提供以下文件app/models/statistic.rb

class Statistic
  # some model code here
end

class UsersStatistic < Statistic; end
class CommentsStatistic < Statistic; end
class ConnectionsStatistic < Statistic; end

创建文件config/initializers/autoload_classes.rb并添加以下代码:

# Autoloading subclasses that are in the same file


# This is the normal way to load single classes
#
# autoload :UsersStatistic, 'statistic'
# autoload :CommentsStatistic, 'statistic'
# autoload :ConnectionsStatistic, 'statistic'


# This is the most dynamic way for production and development environment.
Statistic.subclasses.each do |klass|
  autoload klass.to_s.to_sym, 'statistic'
end



# This does the same but loads all subclasses automatically. 
# Useful only in production environment because every file-change 
# needs a restart of the rails server.
# 
# Statistic.subclasses