8

我有以下设置:

应用程序/模型/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/service/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 引擎

rails plugin new MyModule
4

1 回答 1

13

默认情况下,在开发环境中,Rails 将app通过查找常规位置(例如/app/models/my_module/service/rack.rbfor MyModule::Service::Rack)来自动加载 的常用子目录中的常量。这种自动加载发生在第一次引用常量时,而不是在应用程序初始化时。

但这意味着在引用常量之前,除非明确要求,否则不会加载定义它的文件。

因此,当您调用MyModule::Service.raw_types,时,如果它尚未定义,MyModule::Service则从它加载。app/models/my_module/service.rb但是,如果尚未对其子类进行引用,则不会定义这些常量,除非明确需要定义它们的文件。因此,需要在该方法调用上自动加载的文件中的那些文件使它们可用

道德:如果你想确保MyModule::Service无论何时总是定义的子类MyModule::Service,你需要在/app/models/my_module/service.rb

于 2013-05-15T17:35:02.167 回答