ChatGPT解决这个技术问题 Extra ChatGPT

How do I get the name of a Ruby class?

How can I get the class name from an ActiveRecord object?

I have:

result = User.find(1)

I tried:

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

I need only the class name, in a string (User in this case). Is there a method for that?

I know this is pretty basic, but I searched both Rails' and Ruby's docs, and I couldn't find it.

@Oliver N.: With normal Ruby objects, Object#class.inspect gives the same as Object#class.name, whereas this isn't the case with ActiveRecord objects.

H
Hans Z

You want to call .name on the object's class:

result.class.name

When I do this I get the Module names before it, so "Module::SubModule::Class", is there a way of getting just "Class"
@Abe: result.class.name.split('::').last
@Abe: even cleaner (ActiveSupport): result.class.name.demodulize
For the newcomers out there, you can also obtain the class name as a string by using the class like this: User.name. User.to_s also seems to work.
The demodulize method comes from here: apidock.com/rails/ActiveSupport/Inflector/demodulize (You need to load the ActiveSupport string inflections to be able to use if, if you are not a Rails project.)
D
Darren Hicks

Here's the correct answer, extracted from comments by Daniel Rikowski and pseidemann. I'm tired of having to weed through comments to find the right answer...

If you use Rails (ActiveSupport):

result.class.name.demodulize

If you use POR (plain-ol-Ruby):

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

An answer that is comparing a solution to others and claims to better, should also explain why.
t
the Tin Man

Both result.class.to_s and result.class.name work.


But conceptually, #name returns the name, #to_s returns a string representation, which just happens to be identical to the name. I'd stick to using #name, just out of anal-retentiveness.
j
jayhendren

If you want to get a class name from inside a class method, class.name or self.class.name won't work. These will just output Class, since the class of a class is Class. Instead, you can just use name:

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

Foo::Bar.say_name

output:

I'm a Foo::Bar!

J
Jignesh Gohel

In my case when I use something like result.class.name I got something like Module1::class_name. But if we only want class_name, use

result.class.table_name.singularize