ruby mengubah nama kelas dalam string menjadi kelas sebenarnya


88

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_commentableplugin tersebut, dan ini menyimpan commentable_type sebagai kolom. Saya ingin dapat memanggil kelas tertentu yang dapat dikomentari untuk melakukannya find(commentable_id).

Terima kasih.

Jawaban:


132

Saya pikir apa yang Anda inginkan adalah constantize

Itu adalah konstruksi RoR. Saya tidak tahu apakah ada satu untuk inti ruby


sempurna, itulah yang saya cari.
disortir

40
Untuk Ruby biasa, Anda akan menggunakan Module.const_get. Keuntungannya constantizeadalah ia bekerja bahkan dengan ruang nama yang sangat bersarang, sehingga Anda bisa melakukan 'Functional::Collections::LazyList'.constantizedan mendapatkan kelas LazyList dari modul Koleksi di modul Fungsional, sedangkan dengan const_get, Anda harus melakukan sesuatu seperti 'Functional::Collections::LazyList'.split('::').reduce(Module, :const_get).
Chuck

46
"Object".constantize # => Object

Harap dicatat bahwa .constantizeini adalah metode Rails, Anda tidak akan menemukannya di Ruby biasa
Edgar Ortega

35

Diberikan 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

10
Anda harus menggunakan camelize daripada classify karena classify adalah untuk nama tabel dan tidak menangani pluralisasi dengan baik.
Peter Brown

2
Jawaban Anda sangat berharga, tetapi Anda harus menggunakan "titleize" untuk nama tabel yang menyertakan spasi, dan hapus spasi dari string untuk membuat arti nama kelas lengkap.
SSR

22

Saya tahu ini adalah pertanyaan lama tetapi saya hanya ingin meninggalkan catatan ini, mungkin berguna untuk orang lain.

Di Ruby biasa, Module.const_getdapat 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")


6

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`
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.