Как я могу получить название класса 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

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!

3

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

result.class.table_name.singularize

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.