Ruby on rails 强制rails自动加载类

Ruby on rails 强制rails自动加载类,ruby-on-rails,ruby,autoload,Ruby On Rails,Ruby,Autoload,我在/app/models的单个文件中有几个小类,类似于: # /app/models/little_class.rb class LittleClass; ...do stuff; end; class AnotherLittleClass; ...do stuff; end; Rails似乎只适合在反映类名的文件中自动加载类。因此,在引用LittleClass之前,引用文件外部的另一个LittleClass会引发如下“Unitized constant”错误: irb(main):001:

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

# /app/models/little_class.rb
class LittleClass; ...do stuff; end;
class AnotherLittleClass; ...do stuff; end;
Rails似乎只适合在反映类名的文件中自动加载类。因此,在引用LittleClass之前,引用文件外部的另一个LittleClass会引发如下“Unitized constant”错误:

irb(main):001:0> AnotherLittleClass 
NameError: uninitialized constant AnotherLittleClass
irb(main):02:0> LittleClass
=> LittleClass
irb(main):03:0> AnotherLittleClass
=> LittleClass2
将它们分割成单独的文件将是一种痛苦和混乱。有没有办法自动加载这些类,这样引用另一个没有LittleClass的LittleClass不会出错?

试试这个技巧:

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> 
1.9.2p312:001>另一个LittleClass.new
#=>NameError:未初始化的常量AnotherLittleClass
1.9.2p312:002>自动加载:另一个LittleClass,File.dirname(_File__)+“/app/models/little_class.rb”
#=>零
1.9.2p312:003>另一个LittleClass.new
# => # 

您可以将它们放在一个模块中,并在此命名空间中使用它们

# /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

在我看来,这是你的选择:

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

  • 将类似以下内容添加到启动文件:

    %W[
        Class1 Class2
        Class3 Class4 Class4
    ].map(&:to_sym).each dp |klass|
        autoload klass,Rails.application.config.root + "/path/to/lib/file"
    end
    
    当然,每次向文件中添加新类时,都必须更新该类

  • 将所有类移动到模块/类名称空间中,并调用
    autoload
    如上所述添加它

  • 只需使用
    require
    将整个文件预先加载到启动文件中即可。扪心自问:额外的努力是否保证延迟加载此文件


  • 给出了以下文件
    app/models/statistic.rb

    class Statistic
      # some model code here
    end
    
    class UsersStatistic < Statistic; end
    class CommentsStatistic < Statistic; end
    class ConnectionsStatistic < Statistic; end
    

    嗯,明白了。但是我不得不手动指定所有的类,这让我很恼火。谢谢@warhog,不过,如果您关心这个问题,这个技巧将打破Rails对类的重新加载。因此,如果您要对这些类进行任何更改,则必须重新启动应用程序。
    class Statistic
      # some model code here
    end
    
    class UsersStatistic < Statistic; end
    class CommentsStatistic < Statistic; end
    class ConnectionsStatistic < Statistic; end
    
    # 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