Как я могу получить название класса Ruby?

392

Как я могу получить имя класса из объекта ActiveRecord?

Я имею:

result = User.find(1)

Я старался:

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

Мне нужно только имя класса в строке ( Userв этом случае). Есть ли способ для этого?

Я знаю, что это довольно просто, но я искал документы как по Rails, так и по Ruby, но не смог найти.

и я
источник
1
@Oliver N .: С обычными объектами Ruby Object#class.inspectдает то же самое Object#class.name, что и в случае с объектами ActiveRecord.
Эндрю Гримм

Ответы:

732

Вы хотите вызвать .name в классе объекта:

result.class.name
flicken
источник
4
Когда я делаю это, я получаю имена модулей перед ним, поэтому «Module :: SubModule :: Class», есть ли способ получить просто «Class»
Abe Petrillo
25
@Abe:result.class.name.split('::').last
Даниэль Риковски
90
@Abe: еще чище (ActiveSupport):result.class.name.demodulize
pseidemann
2
Для новичков там, вы можете также получить имя класса в виде строки, используя класс вроде этого: User.name. User.to_sтоже похоже на работу.
Дэн Политес
Метод demodulize происходит отсюда: apidock.com/rails/ActiveSupport/Inflector/demodulize (вам нужно загрузить строки ActiveSupport, чтобы иметь возможность использовать if, если вы не являетесь Rails-проектом.)
Per Lundberg
118

Вот правильный ответ, извлеченный из комментариев Даниэля Риковского и Псейдемана. Я устала от того, что надо пролистывать комментарии, чтобы найти правильный ответ ...

Если вы используете Rails (ActiveSupport):

result.class.name.demodulize

Если вы используете POR (plain-ol-Ruby):

result.class.name.split('::').last
Даррен Хикс
источник
34

Оба result.class.to_sи result.class.nameработают.

тал
источник
34
Но концептуально #name возвращает имя, #to_s возвращает строковое представление, которое просто совпадает с именем. Я бы придерживался #name, просто из-за анальной сдержанности.
KCH
7

Если вы хотите получить имя класса из метода класса, class.nameили self.class.nameне будет работать. Они будут просто выводить Class, так как класс класса есть Class. Вместо этого вы можете просто использовать name:

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

Foo::Bar.say_name

вывод:

I'm a Foo::Bar!
jayhendren
источник
3

В моем случае, когда я использую что-то вроде, result.class.nameя получил что-то вроде Module1::class_name. Но если мы только хотим class_name, используйте

result.class.table_name.singularize

Чиворн Коуч
источник