Как использовать i18n с Rails 4 enumsми

Rails 4 Active Record Enums отличные, но каков правильный шаблон для перевода с i18n?

Я тоже не нашел никакого конкретного шаблона, поэтому я просто добавил:

en: user_status: active: Active pending: Pending... archived: Archived 

к произвольному .yml-файлу. Тогда в моих взглядах:

 I18n.t :"user_status.#{user.status}" 

Начиная с Rails 5, все модели будут наследоваться от ApplicationRecord .

 class User < ApplicationRecord enum status: [:active, :pending, :archived] end 

Я использую этот суперclass для реализации общего решения для перевода перечислений:

 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] 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 

Чтобы интернационализация была похожа на любой другой атрибут, я следил за вложенным атрибутом, как вы можете видеть здесь .

Если у вас есть 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]) 

Я создал для этого камень.

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 или любым другим classом с геттерами / сеттерами:

https://github.com/viniciusoyama/translated_attribute_value

Попытайтесь использовать gem 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 

Объединив ответы от Repolês и Aliaksandr для Rails 5, мы можем построить 2 метода, которые позволят вам перевести одно значение или набор значений из атрибута enum.

Настройте переводы в файле .yml :

 en: activerecord: attributes: user: statuses: active: "Active" pending: "Pending" archived: "Archived" 

В classе 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 

В наших представлениях мы можем затем перевести отдельные значения:

 

User Status: <%= User.translate_enum_name :status, @user.status %>

Или весь набор значений enums:

 <%= f.select(:status, User.translate_enum_collection :status) %> 

Попробуйте камень enum_help . Из описания:

Справка Функция ActiveRecord :: Enum отлично работает с 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 

ru.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 

Я предпочитаю простой помощник в 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 
  • Странная ошибка в рельсах - отсутствует помощник
  • Тип данных Postgres JSON Rails
  • Rails 4: организовать модели рельсов в подпути без шаблонов имен?
  • С Rails 4 Model.scoped устарел, но Model.all не может его заменить
  • rails 4: страницы пользовательских ошибок для 404, 500 и откуда отправляется сообщение об ошибке по умолчанию 500?
  • Rails 4: как использовать Sass Mappings?
  • Bootstrap 3 + Rails 4 - Некоторые глификоны не работают
  • GroupingError: ERROR: столбец должен отображаться в предложении GROUP BY или использоваться в агрегатной функции
  • Как интегрировать тему Wrap Bootstrap в приложение Rails?
  • Давайте будем гением компьютера.