2012-04-07 4 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 

Было бы боль и запутанна, чтобы разделить их на отдельные файлы. Есть ли способ автозагрузки этих классов, поэтому ссылка на AnotherLittleClass без LittleClass не вызывает ошибку?

ответ

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

Хммм, что получает его. Bummer, что я должен вручную указать все классы. Спасибо @WarHog –

+0

Однако этот трюк сломает перезагрузку классов Rails, если вам это интересно. Поэтому, если вы внесете какие-либо изменения в эти классы, вам придется перезапустить приложение. –

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

Еще один хороший вариант –

1

Это ваш выбор, как я это вижу:

  1. разделите файл на один файл в каждом классе, поместите их в каталог, названный в соответствии с соглашением о рельсах (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 
Смежные вопросы