ruby convierte el nombre de la clase en una cadena a la clase real


87

¿Cómo llamo a una clase desde una cadena que contiene ese nombre de clase dentro de ella? (Supongo que podría hacer caso / cuándo, pero eso parece feo).

La razón por la que pregunto es porque estoy usando el acts_as_commentablecomplemento, entre otros, y estos almacenan commentable_type como una columna. Quiero poder llamar a cualquier clase comentable en particular para hacer un comentario find(commentable_id).

Gracias.

Respuestas:


131

Creo que lo que quieres es constantize

Esa es una construcción RoR. No se si hay uno para ruby ​​core


perfecto, eso es justo lo que estaba buscando.
sin clasificar

40
Para Ruby simple, usarías Module.const_get. La ventaja de constantizees que funciona incluso con espacios de nombres profundamente anidados, por lo que podría hacer 'Functional::Collections::LazyList'.constantizey obtener la clase LazyList del módulo Colecciones en el módulo Funcional, mientras que con const_get, tendría que hacer algo como 'Functional::Collections::LazyList'.split('::').reduce(Module, :const_get).
Chuck

45
"Object".constantize # => Object

Tenga en cuenta que .constantizees un método Rails, no lo encontrará en Ruby simple
Edgar Ortega

34

Dada una cadena, primero llame a classify para crear un nombre de clase (sigue siendo una cadena), luego llame a constantize para intentar encontrar y devolver la constante de nombre de clase (tenga en cuenta que los nombres de clase son constantes ).

some_string.classify.constantize

10
Debe usar camelize en lugar de classify, ya que classify es para nombres de tablas y no maneja muy bien la pluralización.
Peter Brown

1
¡Gracias! ¡eso es genial!
duykhoa

2
Su respuesta es realmente valiosa, pero debe usar "titleize" para el nombre de la tabla que incluye el espacio, y eliminar el espacio en blanco de la cadena para que signifique el nombre completo de la clase.
SSR

22

Sé que esta es una pregunta antigua, pero solo quiero dejar esta nota, puede ser útil para otros.

En Ruby simple, Module.const_getpuede encontrar constantes anidadas. Por ejemplo, tener la siguiente estructura:

module MyModule
  module MySubmodule
    class MyModel
    end
  end
end

Puede usarlo de la siguiente manera:

Module.const_get("MyModule::MySubmodule::MyModel")
MyModule.const_get("MySubmodule")
MyModule::MySubmodule.const_get("MyModel")


6

Si desea convertir la cadena al nombre de la clase actual para acceder al modelo o cualquier otra clase

str = "group class"

> str.camelize.constantize 'or'
> str.classify.constantize 'or'
> str.titleize.constantize

Example :
  def call_me(str)
    str.titleize.gsub(" ","").constantize.all
  end

Call method : call_me("group class")

Result:
  GroupClass Load (0.7ms) SELECT `group_classes`.* FROM `group_classes`
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.