Localize your Rails enums

Juraj Kostolanský February 26, 2019

When Rails 4.1 was released, it came out with a bunch of new features. One of those was ActiveRecord enums.

class Conversation < ApplicationRecord
  enum status: [:active, :archived]
end

conversation = Conversation.create(status: :active)
conversation.status # => "active"

This is a handy feature. However, if you try to localize your Rails app, for example for some select boxes, or just to show the current value, you will quickly realize that there is no built-in feature to translate the enum values.

Starting from Rails 5, all models will inherit from ApplicationRecord. We can use that to create our universal solution.

class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  def self.human_enum_name(enum_name, enum_value)
    enum_i18n_key = enum_name.to_s.pluralize
    I18n.t("activerecord.attributes.#{model_name.i18n_key}.#{enum_i18n_key}.#{enum_value}")
  end
end

This little method allows us to use the locale files in the following way:

en:
  activerecord:
    attributes:
      conversation:
        statuses:
          active: Active conversation
          archived: Archived conversation

Then, we can simply use the class method human_enum_name:

Conversation.human_enum_name(:status, :active) # => "Active conversation"

And with an instance:

conversation = Conversation.create(status: :active)
Conversation.human_enum_name(:status, conversation.status) # => "Active conversation"

Actually, I use this approach quite often, so I’ve built a little gem called human_enum_name. Feel free to use it!

And, if you want to manage your YAML translation files in a clever way, check out my project LocaleData.com.

Let's stay in touch

Do you like what you read? Subscribe to get my content on web development, programming, system administration, side projects and more. No spam, unsubscribe at any time.