2010-11-14 9 views
5

Tengo un objeto modelo que subclasifica ActiveRecord. Además, al usar STI, he definido subclases de este objeto, que definen diferentes tipos y comportamientos. La estructura es como la siguiente:Cómo obtener una matriz de subclases en Rails

class AppModule < ActiveRecord::Base 
    belongs_to :app 
end 

class AppModuleList < AppModule 

end 

class AppModuleSearch < AppModule 

end 

class AppModuleThumbs < AppModule 

end 

Ahora, en una vista donde el usuario tiene la opción de crear nuevos AppModules, me gustaría que para seleccionar de un menú desplegable. Sin embargo no he podido obtener una lista de las subclases de AppModule utilizando las subclases() Método:

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

me sale:

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

lo agradecería cualquier ayuda. ¡Muchas gracias!

+0

¿Qué versión de Ruby on Rails estás usando? – outis

+0

Rails 2.3.8, Ruby 1.8.7 –

+0

La clase tiene un método 'descendientes' en [3.0.0] (http://rubydoc.info/docs/rails/3.0.0/Class#descendants-instance_method), pero no [2.3.8] (http://rubydoc.info/docs/rails/2.3.8/Class#descendants-instance_method). – outis

Respuesta

10

Parece que subclasses y similares es recent addition (el método existe en varias clases en varios momentos, pero se siguió mezclando y eliminando, ese enlace parece ser el primer punto en el que se mantuvo el método) . Si la actualización a la versión más reciente de RoR no es una opción, puede escribir su propio subclasses y completarlo usando Class#inherited (que es lo que hace el descendents_tracker de RoR).

+1

Para cualquier persona dirigida aquí por Google, si sus clases son cargadas de manera diferida, DescendantsTracker no las conocerá hasta que las use. –

5

AppModule.descendants.map &:name es lo que estás buscando. Como en:

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