5
\$\begingroup\$

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
\$\endgroup\$
  • \$\begingroup\$ What do you need the name for? For certain situations, there may be shortcuts. Nothing wrong with your solution though. \$\endgroup\$ – Flambino Mar 2 '13 at 22:36
  • \$\begingroup\$ 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. \$\endgroup\$ – user22717 Mar 3 '13 at 1:07
10
\$\begingroup\$

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
\$\endgroup\$
  • \$\begingroup\$ This is exactly what I was looking for. Thank you! \$\endgroup\$ – user22717 Mar 3 '13 at 10:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.