Ruby konvertiert den Klassennamen in einer Zeichenfolge in eine tatsächliche Klasse


86

Wie rufe ich eine Klasse aus einer Zeichenfolge auf, die diesen Klassennamen enthält? (Ich denke, ich könnte Fall / wann tun, aber das scheint hässlich.)

Der Grund, den ich frage, ist, dass ich acts_as_commentableunter anderem das Plugin verwende und diese den commentable_type als Spalte speichern. Ich möchte in der Lage sein, jede bestimmte kommentierbare Klasse aufzurufen, um eine find(commentable_id)Aktion durchzuführen.

Vielen Dank.

Antworten:


129

Ich denke was du willst ist constantize

Das ist ein RoR-Konstrukt. Ich weiß nicht, ob es einen für Ruby Core gibt


Perfekt, genau das habe ich gesucht.
unsortiert

40
Für einfaches Ruby würden Sie verwenden Module.const_get. Der Vorteil constantizeist , dass es auch bei tief verschachtelten Namensräumen funktioniert, so dass Sie tun könnten 'Functional::Collections::LazyList'.constantizeund die Klasse LazyList von den Modulsammlungen im Modul Funktions, während mit bekommen const_get, würden Sie so etwas wie zu tun haben 'Functional::Collections::LazyList'.split('::').reduce(Module, :const_get).
Chuck


33

Eine Zeichenfolge, erste Anruf gegeben Klassifizieren einen Klassennamen (noch ein String), dann rufen erstellen constantize zu versuchen , den Klassennamen Konstante (beachten Sie, dass zu finden und das Rückklassennamen Konstanten sind ).

some_string.classify.constantize

10
Sie sollten camelize anstelle von classify verwenden, da classify für Tabellennamen gilt und die Pluralisierung nicht sehr gut handhabt.
Peter Brown

1
Vielen Dank! das ist großartig!
Duykhoa

2
Ihre Antwort ist wirklich wertvoll, aber Sie sollten "titleize" für den Tabellennamen verwenden, der nach Leerzeichen enthält, und Leerzeichen aus der Zeichenfolge entfernen, um einen vollständigen Klassennamen zu erhalten.
SSR

22

Ich weiß, dass dies eine alte Frage ist, aber ich möchte nur diese Notiz hinterlassen, sie kann für andere hilfreich sein.

Module.const_getKann im einfachen Ruby verschachtelte Konstanten finden. Zum Beispiel mit folgender Struktur:

module MyModule
  module MySubmodule
    class MyModel
    end
  end
end

Sie können es wie folgt verwenden:

Module.const_get("MyModule::MySubmodule::MyModel")
MyModule.const_get("MySubmodule")
MyModule::MySubmodule.const_get("MyModel")


6

Wenn Sie eine Zeichenfolge in einen tatsächlichen Klassennamen konvertieren möchten, um auf das Modell oder eine andere Klasse zuzugreifen

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`
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.