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źć.

i ja
źródło
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
wzdrygnąć się
źródło
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
Darren Hicks
źródło
34

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

tal
źródło
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!
jayhendren
źródło
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

Chivorn Kouch
źródło