Подтвердить что ты не робот

Интернационализация для констант-хешей в рельсах 3

Не могли бы вы рассказать мне, какая наилучшая практика для хранения констант с интернационализацией в rails3?

f.e. Я хочу иметь постоянный хэш для 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"
4b9b3361

Ответ 1

Я бы предложил следующее. Создайте строковый столбец для цвета волос. Обычно это будет столбцом перечисления (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

Тогда в config/locales/en.yml:

en:
  user:
    hair_colours:
      brown: brown
      white: white
      red: red
      dark_brown: dark brown

И в config/locales/de.yml:

de:
  user:
    hair_colours:
      brown: braun
      white: weiss
      red: rot
      dark_brown: dunkelbraun

В любом представлении вы можете:

<%= t "user.hair_colours.#{@user.hair_colour}" %>

Или вы можете написать вспомогательный метод в app/helpers/users_helper.rb:

def translated_hair_colour(user)
  t "user.hair_colours.#{user.hair_colour}"
end

Поскольку я считаю, что перевод в принципе вызывает озабоченность в представлении, я бы не создал метод в модели User, но в принципе вам ничего не мешает:

class User
  # ...

  def hair_colour_name
    I18n.t "user.hair_colours.#{hair_colour}"
  end
end

Update:

Создание полей выбора в представлении, которое может быть переведено, может быть выполнено двумя способами. первый вариант - использовать переведенные значения в качестве источника. Для этого требуется, чтобы переводы были полными и точными. Если не все значения переведены, отсутствующие значения не будут отображаться в окне выбора.

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

второй вариант - использовать значения валидации в вашей модели. Это "правильный" способ, но для этого требуется небольшая корректировка настройки.

class User < ActiveRecord::Base
  HAIR_COLOURS = %w{brown white red dark_brown}
  validates_inclusion_of :hair_colour, :in => HAIR_COLOURS
end

Теперь в ваших представлениях:

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

Конечно, отображение может быть легко извлечено в помощник.