How to get human readable class name in Ruby on Rails?

11.7k Views Asked by At

I am building an application with Ruby 1.9.3 and Rails 3.0.9

I have a class like below.

module CDA
  class Document
    def humanize_class_name
      self.class.name.gsub("::","")
    end
  end
end

I want the class name like "CDADocument".

Is my humanize_class_name method is the correct way to achieve this?

OR

Any other built in methods available with Rails?

3

There are 3 best solutions below

3
On BEST ANSWER

I think Rails might have something similar, but since the form you want is peculiar, you will have to design the method by yourself. The position where you define it is wrong. You would have to do that for each class. Instead, you should define it in Class class.

class Class
    def humanize_class_name
      name.delete(":")
    end
end
some_instance.class.humanize_class_name #=> the string you want

or

class Object
    def humanize_class_name
        self.class.name.delete(":")
    end
end
some_instance.humanize_class_name #=> the string you want
0
On

There's already an accepted answer for this but I thought I'd share what I did that solved this problem without using any Rails stuff. It accounts for :: in the class names and everything.

def self.humanize_class_name
  self.inspect.scan(/[A-Z][a-z]+/).join(' ')
end

What this does is takes the stringified class name (self.inspect) and then .scan creates an array of any strings of characters within that class name that match the regexes, which join then joins into a single string, placing a space between each word. In this case, the regex /[A-Z][a-z]+/ selects all strings in the word that consist of a single capital letter followed by one or more lower-case letters.

You'd have to modify the regex if any of your class names contained multiple consecutive capital letters, especially if the consecutive capitals could belong to different words (e.g., a class called MyJSONParser should be humanised as "My JSON Parser", whereas the regex above would render it as "My Parser" since the consecutive capitals would be ignored).

Note that the method as I've written it also assumes it is a class method. An instance method would look like this:

def humanize_class_name
  self.class.inspect.scan(/[A-Z][a-z]+/).join(' ')
end

I hope this is helpful to someone!

0
On

If you using i18n you can call Model.model_name.human to get the localized model name.

E.g.: Event.model_name.human returns my localized name.

Docs: http://api.rubyonrails.org/classes/ActiveModel/Name.html#method-i-human