如何在Rails 4枚举中使用i18n

Chr*_*eck 75 enums ruby-on-rails-4

Rails 4 Active Record Enums非常棒,但使用i18n进行翻译的正确模式是什么?

Rep*_*lês 62

从Rails 5开始,所有模型都将继承自ApplicationRecord.

class User < ApplicationRecord
  enum status: [:active, :pending, :archived]
end
Run Code Online (Sandbox Code Playgroud)

我使用这个超类来实现翻译枚举的通用解决方案:

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
Run Code Online (Sandbox Code Playgroud)

然后我在我的.yml文件中添加翻译:

en:
  activerecord:
    attributes:
      user:
        statuses:
          active: "Active"
          pending: "Pending"
          archived: "Archived"
Run Code Online (Sandbox Code Playgroud)

最后,为了获得我使用的翻译:

User.human_enum_name(:status, :pending)
=> "Pending"
Run Code Online (Sandbox Code Playgroud)

  • @tirdadc你可以像这样处理一个下拉列表:`<%= f.select:status,User.statuses.keys.collect {| status | [User.human_enum_name(:status,status),status]}%>`. (4认同)
  • 如何在下拉列表中处理(即不显示单个值时)? (3认同)
  • +1好的答案.我调整了它作为一个视图助手方法,因为我觉得这更像是一个视图问题,并且没有复制属性名称:https://gist.github.com/abevoelker/fed59c2ec908de15acd27965e4725762在视图中调用它`human_enum_name(@ user,:status)` (3认同)

pie*_*rea 43

我也没有找到任何特定的模式,所以我简单地补充说:

en:
  user_status:
    active:   Active
    pending:  Pending...
    archived: Archived
Run Code Online (Sandbox Code Playgroud)

到一个任意的.yml文件.然后在我看来:

I18n.t :"user_status.#{user.status}"
Run Code Online (Sandbox Code Playgroud)

  • 我做了类似的事情,但我把它放在`{locale} .activerecord.attributes.{model}.{attribute}`下并编写了一个`t_enum(模型,枚举,值)`助手方法,因此枚举翻译将与标签翻译 (5认同)

Ali*_*ndr 30

这是一个观点:

select_tag :gender, options_for_select(Profile.gender_attributes_for_select)
Run Code Online (Sandbox Code Playgroud)

这是一个模型(您可以将此代码实际移动到帮助器或装饰器中)

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
Run Code Online (Sandbox Code Playgroud)

这是locale文件:

en:
  activerecord:
    attributes:
      profile:
        genders:
          male: Male
          female: Female
          trans: Trans
Run Code Online (Sandbox Code Playgroud)


Dog*_*ita 22

为了使国际化与任何其他属性相似,我遵循嵌套属性方式,如您在此处所见.

如果你有一个班级User:

class User < ActiveRecord::Base
  enum role: [ :teacher, :coordinator ]
end
Run Code Online (Sandbox Code Playgroud)

yml这样的:

pt-BR:
  activerecord:
    attributes:
      user/role: # You need to nest the values under model_name/attribute_name
        coordinator: Coordenador
        teacher: Professor
Run Code Online (Sandbox Code Playgroud)

您可以使用:

User.human_attribute_name("role.#{@user.role}")
Run Code Online (Sandbox Code Playgroud)

  • 这在视觉上很吸引人,但它打破了“activerecord.attributes.&lt;fieldname&gt;”作为表单助手的“label”翻译的 Rails 约定 (2认同)
  • @ChrisBeck它似乎遵循Rails I18n指南中描述的约定:http://guides.rubyonrails.org/i18n.html#translations-for-active-record-models (2认同)

Osw*_*ira 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
Run Code Online (Sandbox Code Playgroud)

地点:

checkpoint_stages:
    starting: Saída
    course: Percurso
    ending: Chegada
Run Code Online (Sandbox Code Playgroud)

在视图(.slim)上:

= f.input_field :stage, collection: Checkpoint.i18n_stages, as: :radio_buttons
Run Code Online (Sandbox Code Playgroud)


小智 6

详细阐述user3647358的答案,您可以非常轻松地完成与转换属性名称时所用的操作。

语言环境文件:

en:
  activerecord:
    attributes:
      profile:
        genders:
          male: Male
          female: Female
          trans: Trans
Run Code Online (Sandbox Code Playgroud)

通过调用I18n#t进行翻译:

profile = Profile.first
I18n.t(profile.gender, scope: [:activerecord, :attributes, :profile, :genders])
Run Code Online (Sandbox Code Playgroud)


小智 5

结合RepolêsAliaksandr的答案,对于 Rails 5,我们可以构建 2 种方法,允许您从枚举属性转换单个值或值的集合。

在您的.yml文件中设置翻译:

en:
  activerecord:
    attributes:
      user:
        statuses:
          active: "Active"
          pending: "Pending"
          archived: "Archived"
Run Code Online (Sandbox Code Playgroud)

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 
Run Code Online (Sandbox Code Playgroud)

在我们看来,我们可以翻译单个值:

<p>User Status: <%= User.translate_enum_name :status, @user.status %></p>
Run Code Online (Sandbox Code Playgroud)

或者整个枚举值集合:

<%= f.select(:status, User.translate_enum_collection :status) %>
Run Code Online (Sandbox Code Playgroud)