If I have 4 classes with the following hierarchy:
class MainClass < ActiveRecord::Base
  ...
end
class SubClassA < MainClass
  ...
end
class SubClassB < MainClass
  ...
end
class SubClassC < MainClass
  ...
end
How can I get a list of the subclasses of MainClass without going through and creating instances of each of the other classes?
In a fresh IRB session I can go in and say
irb(main)> MainClass.descendants
=> []
However if I go through and create instances of each subclass I'll see the following
irb(main)> SubClassA.new
=> #<SubClassA ...>
irb(main)> SubClassB.new
=> #<SubClassB ...>
irb(main)> SubClassC.new
=> #<SubClassC ...>
irb(main)> MainClass.descendants
=> [SubClassA(...), SubClassB(...), SubClassC(...)]
I'm basically looking for a way to programmaticly supply all subclasses so in the future when I want to add SubClassD, SubClassE, etc., I won't have to worry that each one is instantiated in the code before the user can see them.
This is an artefact of development mode only loading classes when first referenced: those files haven't been read by the interpreter yet - as far as ruby is concerned the classes genuinely do not exist yet
A workaround is to put
require_dependency "subclass_a"
require_dependency "subclass_b"
....
At the bottom the file for main class (outside the class definition)
There are several ways you can achieve this. Either by using a gem such as the descendants_tracker:
class MainClass < ActiveRecord::Base
  extend DescendantsTracker
end
class SubClassA < MainClass 
end
...
MainClass.descendants # => [SubClassA]
Or you could create a custom one in your parent class like this:
class  MainClass < ActiveRecord::Base
  def self.descendants
    ObjectSpace.each_object(Class).select { |klass| klass < self }
  end
end
class SubClassA < MainClass 
end
class SubClassB  < MainClass 
end
puts MainClass.descendants 
#=> SubClassA
    SubClassB  
You can also check for levels of dependencies. If you want an array of the direct child of MainClass for example you could use the .subclasses class method
MainClass.subclasses  # => [SubClassA, SubClassB,...]
Now if you want more than one level depth of child classes use .descendants. You can find an example here 
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With