3

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

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

Rails 似乎只适合在反映类名的文件中自动加载类。因此,在文件之外引用 AnotherLittleClass 会引发“未初始化常量”错误,如下所示,直到引用 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

4 回答 4

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
于 2012-04-07T20:10:04.777 回答
1

在我看来,这些是您的选择:

  1. 将您的文件拆分为每个类一个文件,将它们放在根据 rails 约定 ( SomeClass=> 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. 问问你自己:额外的努力是否需要延迟这个文件的加载?

于 2012-04-08T13:35:58.937 回答
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> 
于 2012-04-07T20:04:21.730 回答
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
于 2015-08-10T14:19:57.767 回答