Rails 4中的Active Record Enums很好,但在i18n翻译方面,什么是正确的模式?
从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"
我也没有发现任何特定的模式,所以我只是添加了:
en:
user_status:
active: Active
pending: Pending...
archived: Archived
将一个任意的 .yml 文件添加进来。然后在我的视图中:
I18n.t :"user_status.#{user.status}"
{locale}.activerecord.attributes.{model}.{attribute}
下,并编写了一个t_enum(model, enum, value)
辅助方法,使枚举翻译与标签翻译相邻。 - Chris BeckUser
: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}")
activerecord.attributes.<fieldname>
应该作为表单帮助器的 label
翻译。 - Chris Beck这是一个视图:
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
以下是本地化文件:
en:
activerecord:
attributes:
profile:
genders:
male: Male
female: Female
trans: Trans
.human_attribute_name('genders.male')
”无法起作用。 - Stiiggenders.map
的性别是什么?我一直得到undefined local variable or method `genders'
。 - TPR对于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])
结合Repolês和Aliaksandr的答案,对于Rails 5,我们可以构建两种方法,允许您从枚举属性中翻译单个值或一组值。
在您的.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) %>
enum_values.each_with_object({}) do |enum_value, acc|
acc[enum_value] = self.translate_enum_name(enum_name, enum_value)
end
然后在视图中添加一个invert:User.translate_enum_collection(:status).invert
- Jorge Sampayo模型:
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
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
它可以与Active Record、Mongoid或任何具有getter/setter的类一起使用:
尝试使用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
这个模型:
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
@user.role
怎么样,因为这是主要问题。 - Code-MonKy
<%= f.select :status, User.statuses.keys.collect { |status| [User.human_enum_name(:status, status), status] } %>
。 - Repolêshuman_enum_name(@user, :status)
。 - Abe Voelkerself.human_enum_collection(enum_name)
。代码如下:send(enum_name.to_s.pluralize).keys.collect { |val| [human_enum_name(enum_name, val), val] }
。 - armchairdj