2012-04-07 45 views
1

我有几个小班是在/应用/型号的单个文件,类似于:强制导轨自动加载类

# /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不会引发错误?

回答

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> 
+0

嗯,是得到它。我不得不手动指定所有的类。谢谢@WarHog – 2012-04-07 20:34:57

+0

然而,如果你关心这个技巧,Rails会重新加载类。因此,如果您将对这些类进行任何更改,则必须重新启动该应用程序。 – 2016-04-07 16:28:21

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 
+0

另一个不错的选择 – 2012-04-07 20:36:37

1

这是你的选择,因为我看到它内部使用它们:

  1. 将你的文件分割成每个类的一个文件,把它们放在一个根据rails惯例命名的dir中(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加载整个文件的前期的启动文件。问问你自己:额外的努力是否有必要延迟这个文件的加载?

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