轨道中常量哈希的国际化3

Bvu*_*Ic7 20 hash ruby-on-rails constants internationalization ruby-on-rails-3

你能告诉我在rails3中存储国际化常量的最佳实践吗?

我想为我的用户模型使用haircolours的常量哈希值:

# btw: how can I store such hashes in the locales.yml-files?
# en.yml
HAIR_COLOURS = { "brown" => 0, "white" => 1, "red" => 2, "dark-brown" => 3...}

# de.yml
HAIR_COLOURS = { "braun" => 0, "weiss" => 1, "rot" => 2, "dunkel-braun" => 3...}

# i18n.default_locale = :de
User.find(1).haircolour
=> 0
User.find(1).haircolour_str
=> "brown"

# i18n.default_locale = :de
User.find(1).haircolour
=> 0
User.find(1).haircolour_str
=> "braun"
Run Code Online (Sandbox Code Playgroud)

mol*_*olf 30

我建议如下.为头发颜色创建一个字符串列.这通常是枚举列(ENUM),但Rails不支持这种情况,除非您在迁移中使用某些SQL.

在模型中,将颜色限制为几个有效值.

class User < ActiveRecord::Base
  # Store the colours in the database as string identifiers (my preference
  # would be English, lower case, with underscores). Only accept known values.

  validates_inclusion_of :hair_colour, :in => %w{brown white red dark_brown}
end
Run Code Online (Sandbox Code Playgroud)

然后,在config/locales/en.yml:

en:
  user:
    hair_colours:
      brown: brown
      white: white
      red: red
      dark_brown: dark brown
Run Code Online (Sandbox Code Playgroud)

并在config/locales/de.yml:

de:
  user:
    hair_colours:
      brown: braun
      white: weiss
      red: rot
      dark_brown: dunkelbraun
Run Code Online (Sandbox Code Playgroud)

在任何视图中,您都可以:

<%= t "user.hair_colours.#{@user.hair_colour}" %>
Run Code Online (Sandbox Code Playgroud)

或者您可以在app/helpers/users_helper.rb以下位置编写辅助方法:

def translated_hair_colour(user)
  t "user.hair_colours.#{user.hair_colour}"
end
Run Code Online (Sandbox Code Playgroud)

因为我认为翻译原则上是演示文稿的一个问题,我不会在User模型上创建一个方法,但原则上没有什么能阻止你做:

class User
  # ...

  def hair_colour_name
    I18n.t "user.hair_colours.#{hair_colour}"
  end
end
Run Code Online (Sandbox Code Playgroud)

更新:

在翻译的视图中制作选择框可以通过两种方式完成.第一种选择是使用翻译的值作为源.这要求翻译完整准确.如果未翻译所有值,则缺少的值将不会显示在选择框中.

<%= form_for @user do |user| %>
  <%= user.select :hair_colour, t("user.hair_colours").invert %>
  <%= user.submit %>
<% end %>
Run Code Online (Sandbox Code Playgroud)

第二个选项是从模型中使用的验证值.这是"正确的"方式,但需要稍微调整验证设置.

class User < ActiveRecord::Base
  HAIR_COLOURS = %w{brown white red dark_brown}
  validates_inclusion_of :hair_colour, :in => HAIR_COLOURS
end
Run Code Online (Sandbox Code Playgroud)

现在,在您的观点中:

<%= form_for @user do |user| %>
  <%= user.select :hair_colour,
    User::HAIR_COLOURS.map { |c| [t("user.hair_colours.#{c}"), c] } %>
  <%= user.submit %>
<% end %>
Run Code Online (Sandbox Code Playgroud)

当然,映射可以很容易地提取到帮助器中.