Jak uzyskać nazwę klasy Ruby?


392

Jak mogę uzyskać nazwę klasy z obiektu ActiveRecord?

Mam:

result = User.find(1)

Próbowałem:

result.class
# => User(id: integer, name: string ...)
result.to_s
# => #<User:0x3d07cdc>"

Potrzebuję tylko nazwy klasy w ciągu znaków ( Userw tym przypadku). Czy istnieje na to metoda?

Wiem, że to dość proste, ale przeszukałem zarówno dokumenty Railsów, jak i Ruby, i nie mogłem tego znaleźć.


1
@Oliver N .: W przypadku zwykłych obiektów Ruby Object#class.inspectdaje to samo, co Object#class.name, podczas gdy nie dotyczy to obiektów ActiveRecord.
Andrew Grimm,

Odpowiedzi:


732

Chcesz wywołać nazwę .name w klasie obiektu:

result.class.name

4
Kiedy to robię, otrzymuję przed nim nazwy modułów, więc „Module :: SubModule :: Class” jest sposobem na uzyskanie „Class”
Abe Petrillo,

25
@Abe:result.class.name.split('::').last
Daniel Rikowski

90
@Abe: nawet czystsze (ActiveSupport):result.class.name.demodulize
pseidemann

2
Dla nowo przybyłych tam, można również uzyskać nazwę klasy jako ciąg znaków za pomocą klasy tak: User.name. User.to_swydaje się również działać.
Dan Polites,

Metoda demodulize pochodzi stąd: apidock.com/rails/ActiveSupport/Inflector/demodulize (. Musisz załadować tonu ActiveSupport ciągów, aby móc użyć jeśli jeśli nie są projektem Rails)
Per Lundberg

118

Oto poprawna odpowiedź, wyodrębniona z komentarzy Daniela Rikowskiego i pseidemanna. Jestem zmęczony przeglądaniem komentarzy w celu znalezienia właściwej odpowiedzi ...

Jeśli używasz Railsów (ActiveSupport):

result.class.name.demodulize

Jeśli używasz POR (zwykły-ol-Ruby):

result.class.name.split('::').last

34

Zarówno result.class.to_si result.class.namepraca.


34
Ale koncepcyjnie #name zwraca nazwę, #to_s zwraca ciąg znaków, który akurat jest identyczny z nazwą. Pozostałbym przy użyciu #name, po prostu z powodu retencji.
kch

7

Jeśli chcesz uzyskać nazwę klasy z metody klasowej class.namelub self.class.namenie będzie działać. Będą one po prostu generować Class, ponieważ jest klasą klasy Class. Zamiast tego możesz po prostu użyć name:

module Foo
  class Bar
    def self.say_name
      puts "I'm a #{name}!"
    end
  end
end

Foo::Bar.say_name

wynik:

I'm a Foo::Bar!

3

W moim przypadku, gdy używam czegoś takiego result.class.name, mam coś takiego Module1::class_name. Ale jeśli tylko chcemy class_name, użyj

result.class.table_name.singularize

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.