Bagaimana cara memanggil kelas dari string yang berisi nama kelas di dalamnya? (Saya kira saya bisa melakukan kasus / kapan tetapi itu tampaknya jelek.)
Alasan saya bertanya adalah karena saya menggunakan acts_as_commentable
plugin tersebut, dan ini menyimpan commentable_type sebagai kolom. Saya ingin dapat memanggil kelas tertentu yang dapat dikomentari untuk melakukannya find(commentable_id)
.
Terima kasih.
ruby-on-rails
tidak disortir
sumber
sumber
Module.const_get
. Keuntungannyaconstantize
adalah ia bekerja bahkan dengan ruang nama yang sangat bersarang, sehingga Anda bisa melakukan'Functional::Collections::LazyList'.constantize
dan mendapatkan kelas LazyList dari modul Koleksi di modul Fungsional, sedangkan denganconst_get
, Anda harus melakukan sesuatu seperti'Functional::Collections::LazyList'.split('::').reduce(Module, :const_get)
."Object".constantize # => Object
sumber
.constantize
ini adalah metode Rails, Anda tidak akan menemukannya di Ruby biasaDiberikan string, panggilan pertama classify untuk membuat nama kelas (masih string), kemudian panggil constantize untuk mencoba menemukan dan mengembalikan nama kelas konstan (perhatikan bahwa nama kelas adalah konstanta ).
some_string.classify.constantize
sumber
Saya tahu ini adalah pertanyaan lama tetapi saya hanya ingin meninggalkan catatan ini, mungkin berguna untuk orang lain.
Di Ruby biasa,
Module.const_get
dapat menemukan konstanta bersarang. Misalnya, memiliki struktur berikut:module MyModule module MySubmodule class MyModel end end end
Anda dapat menggunakannya sebagai berikut:
Module.const_get("MyModule::MySubmodule::MyModel") MyModule.const_get("MySubmodule") MyModule::MySubmodule.const_get("MyModel")
sumber
Ketika ActiveSupport tersedia (misalnya di Rails):
String#constantize
atauString#safe_constantize
, itulah"ClassName".constantize
.Di Ruby murni:,
Module#const_get
biasanyaObject.const_get("ClassName")
.Dalam rubi baru-baru ini, keduanya bekerja dengan konstanta bersarang di modul, seperti di
Object.const_get("Outer::Inner")
.sumber
Jika Anda ingin mengubah string menjadi nama kelas sebenarnya untuk mengakses model atau kelas lainnya
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`
sumber