2010-11-14 7 views
5

Ho un oggetto modello che sottoclasse ActiveRecord. Inoltre, usando STI, ho definito sottoclassi di questo oggetto, che definiscono diversi tipi e comportamenti. La struttura simile a questa:Come ottenere un array di sottoclassi in Rails

class AppModule < ActiveRecord::Base 
    belongs_to :app 
end 

class AppModuleList < AppModule 

end 

class AppModuleSearch < AppModule 

end 

class AppModuleThumbs < AppModule 

end 

Ora, in una vista in cui l'utente ha la possibilità di creare nuovi AppModules, vorrei loro di selezionare da un menu a discesa. Metodo Tuttavia non sono stato in grado di ottenere un elenco di sottoclassi di AppModule utilizzando le sottoclassi():

<% 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 %> 

ottengo:

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

Apprezzerei tutto l'aiuto. Molte grazie!

+0

Quale versione di Ruby on Rails stai usando? – outis

+0

Rails 2.3.8, Ruby 1.8.7 –

+0

La classe ha un metodo 'descendents' in [3.0.0] (http://rubydoc.info/docs/rails/3.0.0/Class#descendants-instance_method), ma non [2.3.8] (http://rubydoc.info/docs/rails/2.3.8/Class#descendants-instance_method). – outis

risposta

10

Sembra che sia subclasses e simili sia un recent addition (il metodo esiste in varie classi in vari momenti nel tempo, ma continuava a essere mescolato e rimosso, quel collegamento sembra essere il primo punto in cui il metodo si è bloccato) . Se l'aggiornamento alla versione più recente di RoR non è un'opzione, puoi scrivere il tuo subclasses e compilarlo utilizzando Class#inherited (che è ciò che fa RoR descendents_tracker).

+1

Per chiunque diretto qui da Google, se le tue classi sono pigre, DescendantsTracker non ne saprà nulla fino a quando non verranno utilizzate. –

5

AppModule.descendants.map &:name è quello che stai cercando. Come in:

<% 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 %> 
Problemi correlati