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.