Rails 4 Active Record Enums很棒,但使用i18n进行翻译的正确模式是什么?
答案 0 :(得分:51)
从Rails 5开始,所有模型都将继承自ApplicationRecord
。
class User < ApplicationRecord
enum status: [:active, :pending, :archived]
end
我使用这个超类来实现翻译枚举的通用解决方案:
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"
答案 1 :(得分:42)
我也没有找到任何特定的模式,所以我只是添加:
en:
user_status:
active: Active
pending: Pending...
archived: Archived
到任意.yml文件。然后在我看来:
I18n.t :"user_status.#{user.status}"
答案 2 :(得分:29)
以下是一个观点:
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
答案 3 :(得分:20)
为了使国际化与我遵循嵌套属性方式的任何其他属性相似,您可以看到here。
如果您有课程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}")
答案 4 :(得分:7)
型号:
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
答案 5 :(得分:5)
详细说明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])
答案 6 :(得分:4)
尝试将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
答案 7 :(得分:3)
我为此创造了一个宝石。
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
它适用于活动记录,mongoid或任何其他具有getter / setter的类:
答案 8 :(得分:3)
结合Repolês和Aliaksandr的答案,对于Rails 5,我们可以构建2个方法,允许您从枚举属性转换单个值或值集合。
在.yml
文件中设置翻译:
en:
activerecord:
attributes:
user:
statuses:
active: "Active"
pending: "Pending"
archived: "Archived"
在所有模型继承的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) %>
答案 9 :(得分:2)
试试enum_help宝石。从其描述:
帮助ActiveRecord :: Enum功能与I18n和simple_form一起正常工作。
答案 10 :(得分:2)
这是我使用的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"
答案 11 :(得分:2)
模特:
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
答案 12 :(得分:1)
我更喜欢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é"
答案 13 :(得分:0)
另一种方式,我发现使用模型中的问题更方便
关注:
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"
查看:
<% @campaigns.each do |c| %>
<%= c.t_enum("status") %>
<% end %>
不要忘记在模型中添加问题:
class Campaign < ActiveRecord::Base
include EnumTranslation
enum status: [:designed, :created, :active, :failed, :success]
end
答案 14 :(得分:0)
您只需添加帮助程序:
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!"
然后将其与您的选择:my_something_list