Require Dependency to Get Rails Subclasses

I have the following setup:

application / models / 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" 

application / models / my_module / services / rack.rb:

 module MyModule class Service::Rack < Service end end 

application / models / my_module / services / rails.rb:

 module MyModule class Service::Rails < Service end end 

application / models / my_module / services / sinatra.rb:

 module MyModule class Service::Sinatra < Service end end 

This works so far, but now my question is:

Why do I need to add these three lines:

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

to my service.rb file?

If I do not add three lines:

 MyModule::Service.raw_types => [] 

If I add three lines:

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

Anyone have an idea?

Btw: I am using Ruby 2.0.0-preview1, Rails 4.0.0.rc1 and creating a new Rails engine with

 rails plugin new MyModule 
+8
ruby ruby-on-rails ruby-on-rails-4
source share
1 answer

By default, in the development environment, Rails will auto-configure constants in the regular app subdirectories by looking at the usual place (for example, /app/models/my_module/service/rack.rb for MyModule::Service::Rack ). This startup occurs when the constant is referenced for the first time, and not on application initialization.

But this means that prior to referencing a constant, the file that defines it is not loaded unless explicitly required.

Thus, when you call MyModule::Service.raw_types , MyModule::Service loaded from app/models/my_module/service.rb if it is not already defined. However, if references to its subclasses have not yet been made, these constants will not be defined unless the files that define them are explicitly required. Thus, requiring these files in a file that was downloaded using this method makes them available.

Moral: if you want subclasses of MyModule::Service always be defined whenever MyModule::Service , you need to require them in /app/models/my_module/service.rb

+12
source share

All Articles