2010-11-14 9 views
5

Mam obiekt modelu, który podklasuje ActiveRecord. Dodatkowo, używając STI, zdefiniowałem podklasy tego obiektu, które definiują różne typy i zachowania. Struktura wygląda mniej więcej tak:Jak uzyskać tablicę podklas w Railsach

class AppModule < ActiveRecord::Base 
    belongs_to :app 
end 

class AppModuleList < AppModule 

end 

class AppModuleSearch < AppModule 

end 

class AppModuleThumbs < AppModule 

end 

Teraz w widoku, w którym użytkownik ma możliwość tworzenia nowych AppModules chciałbym je wybrać z menu rozwijanego. Jednak nie udało się uzyskać listę podklas AppModule wykorzystaniem podklasy() metoda:

<% form_for(@app_module) do |f| %> 
    <%= f.error_messages %> 

    <p> 
    <%= f.label :type %><br /> 
    <%= f.select(:type, options_from_collection_for_select(@app_module.subclasses().map{ |c| c.to_s }.sort)) %> 
    </p> 
    <p> 
    <%= f.submit 'Create' %> 
    </p> 
<% end %> 

uzyskać:

NoMethodError: undefined method `subclasses' for #<AppModule:0x1036b76d8> 

będę wdzięczny za każdą pomoc. Wielkie dzięki!

+0

Którą wersję Ruby on Rails używasz? – outis

+0

Rails 2.3.8, Ruby 1.8.7 –

+0

Klasa ma metodę "potomków" w [3.0.0] (http://rubydoc.info/docs/rails/3.0.0/Class#descendants-instance_method), ale nie [2.3.8] (http://rubydoc.info/docs/rails/2.3.8/Class#descendants-instance_method). – outis

Odpowiedz

10

Wygląda tak, jakby i tym podobne jest recent addition (metoda istnieje na różnych klasach w różnych punktach w czasie, ale ciągle się tasuje i usuwa, to łącze wydaje się być najwcześniejszym punktem, w którym metoda utknęła) . Jeśli uaktualnienie do najnowszej wersji RoR nie jest opcją, możesz napisać własną wersję subclasses i zapełnić ją przy użyciu Class#inherited (co robi to RoR descendents_tracker).

+1

Dla wszystkich poleconych tutaj przez Google, jeśli twoje zajęcia są leniwy załadowany, DescendantsTracker nie będzie wiedział o nich, dopóki nie zostaną użyte. –

5

AppModule.descendants.map &:name jest tym, czego szukasz. Tak jak w:

<% form_for(@app_module) do |f| %> 
    <%= f.error_messages %> 

    <p> 
    <%= f.label :type %><br /> 
    <%= f.select(:type, options_from_collection_for_select(AppModule.descendants.map(&:name).sort)) %> 
    </p> 
    <p> 
    <%= f.submit 'Create' %> 
    </p> 
<% end %>