443

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.

1
  • 1
    @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. Commented Aug 9, 2011 at 23:53

6 Answers 6

822

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

result.class.name 
Sign up to request clarification or add additional context in comments.

6 Comments

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.)
|
141

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 

2 Comments

An answer that is comparing a solution to others and claims to better, should also explain why.
well, technically, my comment answered more than what was originally asked ;)
39

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

1 Comment

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.
15

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! 

1 Comment

Wow, thanks, that feels counterintuitive, but checks out. It's strange because it feels easy and common to override name, especially in an ActiveRecord model; many models will have a name attribute. If that were the case, how would we get the class name?
3

In Ruby, you'd use the object.class.name method as follows.

module Bank class Account end end irb(main):005:0> account = Bank::Account.new => #<Bank::Account:0x0000000106115b00> irb(main):006:0> account.class.name => "Bank::Account" irb(main):008:0> account.class.name.split("::").last => "Account" 

In Rails, as others mentioned, you can use the demodulize method on a string, which is added by Active Support. It removes the module part from the constant expression in the string.

irb(main):014:0> account.class.name.demodulize => "Account" 

Internally, this method calls the demodulize class method on the ActiveSupport::Inflector class, passing itself as the argument.

# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 166 def demodulize ActiveSupport::Inflector.demodulize(self) end 

The Inflector.demodulize function does the same thing.

demodulize('ActiveSupport::Inflector::Inflections') # => "Inflections" demodulize('Inflections') # => "Inflections" demodulize('::Inflections') # => "Inflections" demodulize('') # => "" 

However, its internal implementation is different than the simple version above.

# File activesupport/lib/active_support/inflector/methods.rb, line 228 def demodulize(path) path = path.to_s if i = path.rindex("::") path[(i + 2)..-1] else path end end 

After converting the path argument to a string, it gets the index of the last occurrence of :: using Ruby's rindex function. If it exists, then it returns the remaining substring. Otherwise, it returns the original string. The array[n..-1] expression returns the substring from n to the last character in the string.

Now I haven't done any benchmark studies to find why Rails uses this alternative approach using rindex (please comment if you know why), but as a code readability enthusiast, I like the first one using the split and last functions.

Source: How to Get an Object's Class Name in Rails

Comments

2

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.