Jak wywołać klasę z łańcucha zawierającego nazwę klasy w środku? (Myślę, że mógłbym zrobić przypadek / kiedy, ale to wydaje się brzydkie.)
Pytam, ponieważ używam acts_as_commentable
między innymi wtyczki i przechowują one parametr commentable_type jako kolumnę. Chcę móc przywołać jakąkolwiek klasę, którą można komentować, aby to zrobiła find(commentable_id)
.
Dzięki.
ruby-on-rails
nieposortowany
źródło
źródło
Module.const_get
. Zaletąconstantize
jest to, że działa nawet z głęboko zagnieżdżonymi przestrzeniami nazw, więc możesz zrobić'Functional::Collections::LazyList'.constantize
i pobrać klasę LazyList z modułu Kolekcje w module Functional, podczas gdy zconst_get
, musisz zrobić coś podobnego'Functional::Collections::LazyList'.split('::').reduce(Module, :const_get)
."Object".constantize # => Object
źródło
.constantize
jest to metoda Railsów, nie znajdziesz jej w zwykłym RubyBiorąc pod uwagę łańcuch, najpierw wywołaj classify, aby utworzyć nazwę klasy (nadal ciąg), a następnie wywołaj constantize, aby spróbować znaleźć i zwrócić stałą nazwy klasy (zwróć uwagę, że nazwy klas są stałymi ).
some_string.classify.constantize
źródło
Wiem, że to stare pytanie, ale chcę tylko zostawić tę notatkę, może być pomocna dla innych.
W zwykłym Rubim
Module.const_get
można znaleźć zagnieżdżone stałe. Na przykład o następującej strukturze:module MyModule module MySubmodule class MyModel end end end
Możesz go użyć w następujący sposób:
Module.const_get("MyModule::MySubmodule::MyModel") MyModule.const_get("MySubmodule") MyModule::MySubmodule.const_get("MyModel")
źródło
Kiedy ActiveSupport jest dostępne (np. W Railsach):
String#constantize
lubString#safe_constantize
, to znaczy"ClassName".constantize
.W czystym Ruby:,
Module#const_get
zazwyczajObject.const_get("ClassName")
.W ostatnich rubinach oba działają ze stałymi zagnieżdżonymi w modułach, na przykład w
Object.const_get("Outer::Inner")
.źródło
Jeśli chcesz przekonwertować ciąg na rzeczywistą nazwę klasy, aby uzyskać dostęp do modelu lub dowolnej innej klasy
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`
źródło