2013-05-15 39 views
8

我有以下設置:需要依賴讓Rails的子類

應用程序/模型/ my_module/service.rb

module MyModule 
    class Service < ActiveRecord::Base 
    def self.types 
     self.subclasses 
    end 

    def self.raw_types 
     self.types.map { |c| c.name.split("::").last } 
    end 
    end 
end 

require_dependency "my_module/service/rack" 
require_dependency "my_module/service/rails" 
require_dependency "my_module/service/sinatra" 

應用程序/模型/ my_module /服務/ rack.rb:

module MyModule 
    class Service::Rack < Service 
    end 
end 

應用程序/模型/ my_module /服務/ rails.rb:

module MyModule 
    class Service::Rails < Service 
    end 
end 

應用程序/模型/ my_module /服務/ sinatra.rb:

module MyModule 
    class Service::Sinatra < Service 
    end 
end 

,到目前爲止的工作,但現在我的問題:

我爲什麼要添加這些三行:

require_dependency "my_module/service/rack" 
require_dependency "my_module/service/rails" 
require_dependency "my_module/service/sinatra" 

我的service.rb文件?

如果我不加三條線:如果我添加了三行

MyModule::Service.raw_types 
=> [] 

MyModule::Service.raw_types 
=> ["Rack", "Rails", "Sinatra"] 

任何人的想法?

順便說一句:我使用Ruby 2.0.0-preview1,Rails的4.0.0.rc1並創建

rails plugin new MyModule 
+0

不MyModule的:: Service.types工作? –

+0

問題爲什麼必須要求文件或爲什麼數組被填充?當你需要這些文件時,你需要添加3個所有子類爲Service的類,因此'Service.subclasses'返回這3個類。 – Kris

+0

想法:其中一個文件monkey-patches「子類」放入Class中。 – User

回答

12

默認情況下,一個新的Rails引擎,在開發環境中,Rails會自動加載的常量在平時子目錄app,通過查看常規位置(例如,/app/models/my_module/service/rack.rbMyModule::Service::Rack)。此自動加載發生在第一次引用常量時,而不是在應用程序初始化時引用。

但是這意味着在引用常量之前,除非明確需要,否則定義它的文件不會被加載。

因此,當您撥打MyModule::Service.raw_types時,MyModule::Service如果尚未定義,則從app/models/my_module/service.rb加載。但是,如果尚未提及其子類,那麼這些常量將不會被定義爲,除非明確要求定義它們的文件。因此,要求文件中的那些的文件在該方法調用時自動加載使其可用。

道德:如果你想確保MyModule::Service子類總是定義每當MyModule::Service是,你需要要求他們在/app/models/my_module/service.rb

+0

好吧,我認爲已經,但我希望,Rails在調用方法時修復了自動加載,因爲類需要通過父類方法調用..可能是Rails錯誤嗎?我瞭解從「ruby視圖」加載,但不能從「rails視圖」加載。 – Mattherick

+2

這不是Rails中的錯誤。如果應用程序不知道它們存在,應該如何知道這些常量是需要的?我認爲在定義超類的文件中要求你的子類是沒有什麼壞處的。或者,您可以將它們全部加載到config/boot.rb中,以便它們在應用程序初始化時位於那裏。 – gregates

+0

但是它會非常好,如果Rails有這樣的行爲,它會搜索子文件夾,這個子文件夾就像父類一樣被調用,以檢查是否有子類定義。那太好了 :)。但無論如何,我只是將通過rails初始化過程加載它們。 – Mattherick