21

Pourriez-vous me dire quelle est la meilleure pratique pour stocker les constantes avec l'internationalisation dans rails3?Internationalisation pour les constantes-hachages dans les rails 3

f.e. Je veux avoir une constante-hachage pour les colorations pour mon modèle d'utilisateur:

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

Répondre

30

Je suggère ce qui suit. Créez une colonne de chaîne pour la couleur des cheveux. Ce serait normalement une colonne d'énumération (ENUM), mais cela n'est pas supporté par Rails, à moins que vous ne soyez d'accord avec du SQL dans vos migrations.

Dans votre modèle, limitez les couleurs à quelques valeurs valides.

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 

Puis, en config/locales/en.yml:

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

Et config/locales/de.yml:

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

En tout état de cause, vous pouvez faire:

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

Ou vous pouvez écrire un méthode d'aide en app/helpers/users_helper.rb:

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

Parce que je crois que la traduction est en principe une préoccupation de la présentation, je ne voudrais pas créer une méthode sur le modèle User, mais en principe, il n'y a rien qui vous empêche de le faire:

class User 
    # ... 

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

Mise à jour:

Faire boîtes de sélection dans une vue qui sont tra nslated peut être fait de deux manières. La première option consiste à utiliser les valeurs traduites en tant que source. Cela nécessite des traductions complètes et précises. Si toutes les valeurs ne sont pas traduites, les valeurs manquantes ne seront pas affichées dans la boîte de sélection.

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

La deuxième option est d'utiliser les valeurs de validation de votre modèle. C'est le "bon" moyen, mais il nécessite un léger ajustement de la configuration de la validation.

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

Maintenant, votre point de vue:

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

Bien sûr, la cartographie peut être facilement extrait en aide.

+0

Hmmm ça sonne bien! Merci! mais y a-t-il peut-être une solution encore plus intelligente? Va vérifier cela comme réponse si la prime ne apporte pas quelque chose de mieux ...! – Lichtamberg

+0

Pourriez-vous me dire comment faire select_boxes avec cette solution? Va marquer votre réponse comme acceptée si vous répondez ... Thx! – Lichtamberg

+0

@Lichtamberg: Pas de problème! La réponse a été mise à jour. – molf

Questions connexes