84 votes

Comment instancier une classe à partir d'une chaîne de noms dans Rails ?

Comment instancier une classe à partir de son nom dans Ruby-on-Rails ?

Par exemple, nous avons son nom dans la base de données au format "ClassName" ou "my_super_class_name".

Comment pouvons-nous créer un objet à partir de ces données ?

Solution :

Je l'ai cherché moi-même, mais je ne l'ai pas trouvé, alors le voici. Méthode API Ruby-on-Rails

name = "ClassName"
instance = name.constantize.new  

Il peut même ne pas être formaté, nous pouvons utiliser la méthode string .classer

name = "my_super_class"
instance = name.classify.constantize.new

Bien sûr, ce n'est peut-être pas très "Rails way", mais cela résout le problème.

87voto

Eugene Rourke Points 2189
klass = Object.const_get "ClassName"

sur les méthodes de classe

class KlassExample
    def self.klass_method
        puts "Hello World from Class method"
    end
end
klass = Object.const_get "KlassExample"
klass.klass_method

irb(main):061:0> klass.klass_method
Hello World from Class method

47voto

maninalift Points 673

D'autres peuvent également rechercher une alternative qui ne génère pas d'erreur si la classe n'est pas trouvée. safe_constantize n'est rien d'autre que cela.

class MyClass
end

"my_class".classify.safe_constantize.new #  #<MyClass:0x007fec3a96b8a0>
"omg_evil".classify.safe_constantize.new #  nil

16voto

Pushp Raj Saurabh Points 937

Vous pouvez simplement convertir une chaîne de caractères et initialiser une classe à partir de celle-ci :

klass_name = "Module::ClassName"
klass_name.constantize

Pour initialiser un nouvel objet :

klass_name.constantize.new

J'espère que cela s'avérera utile. J'espère que cela vous sera utile.

7voto

RubesMN Points 910

Je suis surpris que personne ne tienne compte de la sécurité et du piratage dans ses réponses. L'instanciation d'une chaîne arbitraire qui provient probablement, même indirectement, de l'entrée de l'utilisateur est une source de problèmes et de piratage. Nous devrions/devons tous faire de la liste blanche à moins d'être sûrs que la chaîne est entièrement contrôlée et surveillée.

def class_for(name)
  {
    "foo" => Foo,
    "bar" => Bar,
  }[name] || raise UnknownClass
end

class_for(name_wherever_this_came_from).create!(params_somehow)

Il serait difficile de déterminer arbitrairement les paramètres appropriés sans disposer d'une liste blanche, mais vous comprenez l'idée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X