Интернационализация для констант-хэшей в рельсах 3 - PullRequest
21 голосов
/ 02 сентября 2010

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

например, я хочу иметь постоянный хэш для цветовых схем для моей пользовательской модели:

# 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"

1 Ответ

31 голосов
/ 03 сентября 2010

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

Обновление:

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

<%= 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 %>

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

...