Comment appeler une classe à partir d'une chaîne contenant ce nom de classe à l'intérieur? (Je suppose que je pourrais faire le cas / quand mais cela semble moche.)
La raison pour laquelle je demande est que j'utilise le acts_as_commentable
plugin, entre autres, et que ceux-ci stockent le commentable_type sous forme de colonne. Je veux pouvoir appeler n'importe quelle classe commentable particulière pour en faire un find(commentable_id)
.
Merci.
ruby-on-rails
non trié
la source
la source
Module.const_get
. L'avantage deconstantize
est que cela fonctionne même avec des espaces de noms profondément imbriqués, vous pouvez donc faire'Functional::Collections::LazyList'.constantize
et obtenir la classe LazyList à partir du module Collections dans le module Functional, alors qu'avecconst_get
, vous devez faire quelque chose comme'Functional::Collections::LazyList'.split('::').reduce(Module, :const_get)
."Object".constantize # => Object
la source
.constantize
s'agit d'une méthode Rails, vous ne la trouverez pas en Ruby brutÉtant donné une chaîne, premier appel classify pour créer un nom de classe (toujours une chaîne), puis appelez constantize pour essayer de trouver et de renvoyer la constante de nom de classe (notez que les noms de classe sont des constantes ).
some_string.classify.constantize
la source
Je sais que c'est une vieille question mais je veux juste laisser cette note, cela peut être utile pour d'autres.
En Ruby simple,
Module.const_get
peut trouver des constantes imbriquées. Par exemple, ayant la structure suivante:module MyModule module MySubmodule class MyModel end end end
Vous pouvez l'utiliser comme suit:
Module.const_get("MyModule::MySubmodule::MyModel") MyModule.const_get("MySubmodule") MyModule::MySubmodule.const_get("MyModel")
la source
Quand ActiveSupport est disponible (par exemple dans Rails):
String#constantize
ouString#safe_constantize
, c'est-à-dire"ClassName".constantize
.En pur Ruby:,
Module#const_get
typiquementObject.const_get("ClassName")
.Dans les rubis récents, les deux fonctionnent avec des constantes imbriquées dans des modules, comme dans
Object.const_get("Outer::Inner")
.la source
Si vous souhaitez convertir une chaîne en nom de classe actuall pour accéder au modèle ou à toute autre classe
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`
la source