# Underscore-case version of ActiveRecord model's name

Is there a better way to get the underscore-case version of an ActiveRecord model's name? So far this works, but it's far from ideal:

my_active_record_instance.class.name.underscore

• What do you need the name for? For certain situations, there may be shortcuts. Nothing wrong with your solution though. – Flambino Mar 2 '13 at 22:36
• I have several models that have associated files, stored in the public directory like this: /pdf/#{ model_name }/#{ pubdate }/#{ filename }. model_name is the variable I'm looking for to have one single method for all models. Thanks for the feedback. – user22717 Mar 3 '13 at 1:07

You can use the singular method of ActiveModel::Naming:

ActiveModel::Naming.singular(my_active_record_instance)


Alternatively, you can use the model_name method that's mixed in to ActiveRecord by the same ActiveModel::Naming module. However, it's not available on a record instance, so you still have to go through its class:

my_active_record_instance.class.model_name.singular


or call it directly on the class:

MyActiveRecord.model_name.singular


The ActiveModel::Name instance returned by model_name contains many other inflections and name-related stuff.

You might consider making a module or concern that defines a name_for_path (or something) method, and which you can then include in the relevant models, so you can just call that.

By the way, your solution is not uncommon. I looked at the source for the Paperclip gem, which constructs file paths from model names, and it does pretty much the same thing to get the model's name, (though I don't know if there's a specific reason for it, or if they too could just as well use the approaches above).

However, if you keep your version, you should probably use to_s like Paperclip does:

my_active_record_instance.class.to_s.underscore

• This is exactly what I was looking for. Thank you! – user22717 Mar 3 '13 at 10:30