如何在Rails 4枚举中使用i18n
Rails 4 Active Record Enums很好,但是用i18n翻译的正确模式是什么?
我没有find任何具体的模式,所以我只是补充说:
en: user_status: active: Active pending: Pending... archived: Archived 到一个任意的.yml文件。 那么在我看来:
 I18n.t :"user_status.#{user.status}" 
 从Rails 5开始,所有的模型都将inheritance自ApplicationRecord 。 
 class User < ApplicationRecord enum status: [:active, :pending, :archived] end 
我使用这个超类来实现翻译枚举的通用解决scheme:
 class ApplicationRecord < ActiveRecord::Base self.abstract_class = true def self.human_enum_name(enum_name, enum_value) I18n.t("activerecord.attributes.#{model_name.i18n_key}.#{enum_name.to_s.pluralize}.#{enum_value}") end end 
 然后我在我的.yml文件中添加翻译: 
 en: activerecord: attributes: user: statuses: active: "Active" pending: "Pending" archived: "Archived" 
最后,要获得我使用的翻译:
 User.human_enum_name(:status, :pending) => "Pending" 
这里是一个观点:
 select_tag :gender, options_for_select(Profile.gender_attributes_for_select) 
这里是一个模型(你可以将这段代码实际上移入一个助手或者一个装饰器)
 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 
这里是locale文件:
 en: activerecord: attributes: profile: genders: male: Male female: Female trans: Trans 
为了保持国际化与任何其他属性类似,我遵循嵌套属性的方式,你可以看到这里 。
 如果你有一个class级User : 
 class User < ActiveRecord::Base enum role: [ :teacher, :coordinator ] end 
 像这样的一个yml : 
 pt-BR: activerecord: attributes: user/role: # You need to nest the values under model_name/attribute_name coordinator: Coordenador teacher: Professor 
您可以使用:
 User.human_attribute_name("role.#{@user.role}") 
模型:
 enum stage: { starting: 1, course: 2, ending: 3 } def self.i18n_stages(hash = {}) stages.keys.each { |key| hash[I18n.t("checkpoint_stages.#{key}")] = key } hash end 
地点:
 checkpoint_stages: starting: Saída course: Percurso ending: Chegada 
而在视图(.slim)上:
 = f.input_field :stage, collection: Checkpoint.i18n_stages, as: :radio_buttons 
详细阐述user3647358的答案,您可以非常接近您在翻译属性名称时习惯的内容。
区域文件:
 en: activerecord: attributes: profile: genders: male: Male female: Female trans: Trans 
通过调用I18n#t来翻译:
 profile = Profile.first I18n.t(profile.gender, scope: [:activerecord, :attributes, :profile, :genders]) 
我为此创造了一个gem。
http://rubygems.org/gems/translated_attribute_value
添加到你的gemfile:
 gem 'translated_attribute_value' 
如果您有用户的状态字段:
 pt-BR: activerecord: attributes: user: status_translation: value1: 'Translation for value1' value2: 'Translation for value2' 
在你看来,你可以这样打电话:
 user.status_translated 
它与积极的logging,mongoid或任何其他类与getter / setters:
结合Repolês和Aliaksandr的答案,对于Rails 5,我们可以构build两种方法,允许您从enum属性中翻译单个值或一组值。
 在.yml文件中设置翻译: 
 en: activerecord: attributes: user: statuses: active: "Active" pending: "Pending" archived: "Archived" 
 在所有模型inheritance的ApplicationRecord类中,我们定义了一个处理单个值转换的方法,另一个处理数组的方法是调用它: 
 class ApplicationRecord < ActiveRecord::Base self.abstract_class = true def self.translate_enum_name(enum_name, enum_value) I18n.t("activerecord.attributes.#{model_name.i18n_key}.#{enum_name.to_s.pluralize}.#{enum_value}") end def self.translate_enum_collection(enum_name) enum_values = self.send(enum_name.to_s.pluralize).keys enum_values.map do |enum_value| self.translate_enum_name enum_name, enum_value end end end 
在我们看来,我们可以翻译单一的价值观:
 <p>User Status: <%= User.translate_enum_name :status, @user.status %></p> 
或者是枚举值的整个集合:
 <%= f.select(:status, User.translate_enum_collection :status) %> 
试试enum_help gem。 从其描述:
帮助ActiveRecord ::枚举function与I18n和simple_form正常工作。
  t_enum是我使用的t_enum帮助器方法。 
 <%= t_enum(@user, :status) %> 
enum_helper.rb :
 module EnumHelper def t_enum(inst, enum) value = inst.send(enum); t_enum_class(inst.class, enum, value) end def t_enum_class(klass, enum, value) unless value.blank? I18n.t("activerecord.enums.#{klass.to_s.demodulize.underscore}.#{enum}.#{value}") end end end 
user.rb :
 class User < ActiveRecord::Base enum status: [:active, :pending, :archived] end 
en.yml :
 en: activerecord: enums: user: status: active: "Active" pending: "Pending..." archived: "Archived" 
该模型:
 class User < ActiveRecord::Base enum role: [:master, :apprentice] end 
语言环境文件:
 en: activerecord: attributes: user: master: Master apprentice: Apprentice 
用法:
 User.human_attribute_name(:master) # => Master User.human_attribute_name(:apprentice) # => Apprentice 
另一种方式,我发现使用模型的关注点更方便一些
关心 :
 module EnumTranslation extend ActiveSupport::Concern def t_enum(enum) I18n.t "activerecord.attributes.#{self.class.name.underscore}.enums.#{enum}.#{self.send(enum)}" end end 
阳明:
 fr: activerecord: attributes: campaign: title: Titre short_description: Description courte enums: status: failed: "Echec" 
查看:
 <% @campaigns.each do |c| %> <%= c.t_enum("status") %> <% end %> 
不要忘记在你的模型中增加关注:
 class Campaign < ActiveRecord::Base include EnumTranslation enum status: [:designed, :created, :active, :failed, :success] end 
你可以简单地添加一个帮手:
 def my_something_list modes = 'activerecord.attributes.mymodel.my_somethings' I18n.t(modes).map {|k, v| [v, k]} end 
并通常设置:
 en: activerecord: attributes: mymodel: my_somethings: my_enum_value: "My enum Value!" 
 然后使用它与您的select: my_something_list 
尝试使用TranslateEnum gem来达到这些目的
 class Post < ActiveRecord::Base enum status: { published: 0, archive: 1 } translate_enum :status end Post.translated_status(:published) Post.translated_statuses @post = Post.new(status: :published) @post.translated_status 
我更喜欢application_helper中的一个简单的助手
  def translate_enum(object, enum_name) I18n.t("activerecord.attributes.#{object.model_name.i18n_key}.#{enum_name.to_s.pluralize}.#{object.send(enum_name)}") end 
然后在我的YML文件中:
 fr: activerecord: attributes: my_model: my_enum_plural: pending: "En cours" accepted: "Accepté" refused: "Refusé"