How to use i18n with Rails 4 enums

2019-01-06 10:37发布

Rails 4 Active Record Enums are great, but what is the right pattern for translating with i18n?

16条回答
你好瞎i
2楼-- · 2019-01-06 10:54

The model:

class User < ActiveRecord::Base
  enum role: [:master, :apprentice]
end

The locale file:

en:
  activerecord:
    attributes:
      user:
        master: Master
        apprentice: Apprentice

Usage:

User.human_attribute_name(:master) # => Master
User.human_attribute_name(:apprentice) # => Apprentice
查看更多
时光不老,我们不散
3楼-- · 2019-01-06 10:55

You can simply add a helper:

def my_something_list
  modes = 'activerecord.attributes.mymodel.my_somethings'
  I18n.t(modes).map {|k, v| [v, k]}
end

and set it up as usually:

en:
  activerecord:
    attributes:
      mymodel:
        my_somethings:
           my_enum_value: "My enum Value!"

then use it with your select: my_something_list

查看更多
男人必须洒脱
4楼-- · 2019-01-06 10:57

Yet another way, I find it a bit more convenient using a concern in models

Concern :

module EnumTranslation
  extend ActiveSupport::Concern

  def t_enum(enum)
    I18n.t "activerecord.attributes.#{self.class.name.underscore}.enums.#{enum}.#{self.send(enum)}"
  end
end

YML:

fr:
    activerecord:
      attributes:
        campaign:
          title: Titre
          short_description: Description courte
          enums:
            status:
              failed: "Echec"

View :

<% @campaigns.each do |c| %>
  <%= c.t_enum("status") %>
<% end %>

Don't forget to add concern in your model :

class Campaign < ActiveRecord::Base
  include EnumTranslation

  enum status: [:designed, :created, :active, :failed, :success]
end
查看更多
Melony?
5楼-- · 2019-01-06 10:59

Here is a view:

select_tag :gender, options_for_select(Profile.gender_attributes_for_select)

Here is a model (you can move this code into a helper or a decorator actually)

class Profile < ActiveRecord::Base
  enum gender: {male: 1, female: 2, trans: 3}

  # @return [Array<Array>]
  def self.gender_attributes_for_select
    genders.map do |gender, _|
      [I18n.t("activerecord.attributes.#{model_name.i18n_key}.genders.#{gender}"), gender]
    end
  end
end

And here is locale file:

en:
  activerecord:
    attributes:
      profile:
        genders:
          male: Male
          female: Female
          trans: Trans
查看更多
老娘就宠你
6楼-- · 2019-01-06 11:03

Try the enum_help gem. From its description:

Help ActiveRecord::Enum feature to work fine with I18n and simple_form.

查看更多
乱世女痞
7楼-- · 2019-01-06 11:05

Elaborating on user3647358's answer, you can accomplish that very closely to what you're used to when translating attributes names.

Locale file:

en:
  activerecord:
    attributes:
      profile:
        genders:
          male: Male
          female: Female
          trans: Trans

Translate by calling I18n#t:

profile = Profile.first
I18n.t(profile.gender, scope: [:activerecord, :attributes, :profile, :genders])
查看更多
登录 后发表回答