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.