Search code examples
ruby-on-railssti

Rails 2.3 STI return all child classes


I am using standard STI and want to create an input select on a form whose options are all child type of the parent class. So I'd like Parent.select_options to return ['Child1','Child2','Child3']

class Parent < ActiveRecord::Base
  # kinda what I'd like except the descendants method is undefined in rails 2.3
  def self.select_options
    descendants.map{ |c| c.to_s }.sort
  end
end

class Child1 < Parent
end

class Child2 < Parent
end

class Child3 < Parent
end

view.html.haml

= f.input :parent_id, :as => :select, :collection => Parent.select_options, :prompt => true

UPDATE

Thanks to @nash and @jdeseno just need to add the following initializer using @jdeseno method:

%w[parent child1 child2 child3].each do |c|
  require_dependency File.join("app","models","#{c}.rb")
end

Solution

  • You can add a descendants method by hooking into Class.inherited:

    class Parent
      @@descendants = []
    
      def self.inherited(klass)
        @@descendants << klass
      end
    
      def descendants
        @@descendants
      end
    end
    
    class A < Parent; end
    class B < Parent; end
    class C < Parent; end
    

    Eg:

    irb> Parent.new.descendants
    [A, B, C]