2012-12-28 15 views
56

Come possiamo istanziare classe da suo nome stringa in Ruby-on-Rails?Come istanziare la classe dalla stringa del nome in Rails?

Ad esempio, abbiamo il nome nel database in formato "ClassName" o "my_super_class_name".

Come possiamo creare l'oggetto da esso?

Soluzione:

cercavo io stesso, ma non trovato, ecco che è. Ruby-on-Rails API Method

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

Si può anche non formattato, non possiamo metodo stringa user .classify

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

Naturalmente forse questo è molto 'Rails modo', ma si risolve il suo scopo.

+4

Cordiali saluti, constantize è un metodo comodo ActiveSupport che fa 'Object.const_get' e adesso è un metodo ActiveSupport che cerca di trasformare una stringa in una formattazione classe standard. Quello che state facendo è identica alla risposta di Evginey, con alcuni controlli supplementari. Mentre la costante è probabilmente una soluzione migliore (perché esegue controlli di integrità), aiuta a capire gli strumenti che usi. – quandrum

+0

Grazie per questo, ad essere onesti non ha controllato cosa fa in manuale. –

risposta

57
klass = Object.const_get "ClassName" 

sui metodi di 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 
+0

Con ciò non è possibile accedere ai metodi di classe. La mia soluzione sopra funziona correttamente con i metodi di classe. –

+0

si l'attualità può –

+0

'Caricamento ambiente di sviluppo (Rails 3.2.9) irb (principale): 001: 0> nome =" PartnerGateway " =>" PartnerGateway " irb (principale): 002: 0> klass = nome .constantize.nuovo => # irb (main): 003: 0> klass .name => nil' –

24

Gli altri possono anche essere alla ricerca di un'alternativa che non genera un errore se non riesce a trovare la classe. safe_constantize è proprio questo.

class MyClass 
end 

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

Sono sorpreso che nessuno stia considerando la sicurezza e l'hacking nelle loro risposte. L'istanziazione di una stringa arbitraria probabilmente derivata anche indirettamente dall'input dell'utente sta causando problemi e hacking. Noi tutti dovremmo/dobbiamo essere whitelisting a meno che non siamo sicuri che la stringa è completamente controllato e vigilato

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

class_for(name_wherever_this_came_from).create!(params_somehow) 

Come si sa le params appropriate arbitrariamente senza avere una whitelist sarebbe impegnativo, ma si ottiene l'idea.

0

Si può semplicemente convertire una stringa e inizializzare una classe fuori di esso:

klass_name = "Module::ClassName" 
klass_name.constantize 

per inizializzare un nuovo oggetto:

klass_name.constantize.new 

Spero che questo si rivela utile. Grazie!

Problemi correlati