Перечисления Active Record в Rails 4 великолепны, но каков правильный шаблон для перевода с помощью i18n?
ruby-on-rails-4
enums
Крис Бек
источник
источник
{locale}.activerecord.attributes.{model}.{attribute}
и написалt_enum(model, enum, value)
вспомогательный метод, чтобы перевод enum был рядом с переводом меткиНачиная с 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"
источник
<%= f.select :status, User.statuses.keys.collect { |status| [User.human_enum_name(:status, status), status] } %>
.human_enum_name(@user, :status)
self.human_enum_collection(enum_name)
. Код будетsend(enum_name.to_s.pluralize).keys.collect { |val| [human_enum_name(enum_name, val), val] }
Вот вид:
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')
что не работаютЧтобы интернационализация оставалась такой же, как и для любого другого атрибута, я использовал метод вложенных атрибутов, как вы можете видеть здесь .
Если у вас есть класс
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}")
источник
activerecord.attributes.<fieldname>
бытьlabel
перевод формы хелперовrole
ключа. Гнездиться можноcoordinator
иteacher
прямо подuser
.Модель:
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])
источник
Попробуйте использовать для этих целей гем TranslateEnum
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
источник
Я создал для этого жемчужину.
http://rubygems.org/gems/translated_attribute_value
Добавьте в свой гем-файл:
gem 'translated_attribute_value'
Если у вас есть поле статуса для пользователя:
pt-BR: activerecord: attributes: user: status_translation: value1: 'Translation for value1' value2: 'Translation for value2'
И, на ваш взгляд, вы можете позвонить так:
Он работает с активной записью, монгоидом или любым другим классом с геттерами / сеттерами:
https://github.com/viniciusoyama/translated_attribute_value
источник
Объединяя ответы Реполеша и Александра , для 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) %>
источник
Попробуйте гем enum_help . Из его описания:
источник
Вот
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
источник
@user.role
, что это главная проблема.Я предпочитаю простой помощник в 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é"
источник
Еще один способ, который мне кажется более удобным - использовать озабоченность в моделях.
Беспокойство :
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
источник
Вы можете просто добавить помощника:
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
источник
class ApplicationRecord < ActiveRecord::Base self.abstract_class = true def self.enum(definitions) defind_i18n_text(definitions) if definitions.delete(:_human) super(definitions) end def self.defind_i18n_text(definitions) scope = i18n_scope definitions.each do |name, values| next if name.to_s.start_with?('_') define_singleton_method("human_#{name.to_s.tableize}") do p values values.map { |key, _value| [key, I18n.t("#{scope}.enums.#{model_name.i18n_key}.#{name}.#{key}")] }.to_h end define_method("human_#{name}") do I18n.t("#{scope}.enums.#{model_name.i18n_key}.#{name}.#{send(name)}") end end end end en: activerecord: enums: mymodel: my_somethings: my_enum_value: "My enum Value!" enum status: [:unread, :down], _human: true
источник