44 votes

Ruby on Rails i18n - Vouloir traduire les messages personnalisés dans les modèles

J'ai des attributs avec une validation spéciale où j'utilise la clause message pour afficher un message spécial juste pour cette validation. Voici un exemple :

validates :email, presence:   true, length: { maximum: 60 },
                format:     { with: valid_email_regex, message: "is not a valid email address format." },
                uniqueness: { case_sensitive: false } 

Je voudrais traduire le message ici mais je ne sais pas comment faire.

J'ai vu des exemples où ils tapent quelque chose comme ceci : message : t("quelque_valeur_ici"). Je ne suis pas sûr de la désignation. J'ai essayé quelque chose comme ceci : message : t(:bad_email). J'ai fait ce qui suit dans mon fichier yaml, juste pour essayer quelque chose.

activemodel:
  errors:
    bad_email: "is not a valid email address format."

Lorsque j'ai essayé d'accéder à mon application Rails, j'ai obtenu l'erreur suivante :

ActionView::Template::Error (undefined method `t' for #<Class:0x007fefc1b709e0>)

J'ai également essayé ceci dans mon fichier yaml :

activemodel:
  errors:
    user:
      bad_email: "is not a valid email address format."

J'ai fait des recherches sur ce sujet toute la journée. Tout ce que je trouve, c'est de remplacer les hachages d'erreurs intégrés comme blank ou empty. Existe-t-il un moyen de créer des hachages d'erreurs personnalisés et de les remplacer dans le modèle ? Pour l'instant, je n'arrive pas à faire fonctionner le T tel qu'il est codé. J'espère que le problème vient de la façon dont j'ai configuré mon fichier yaml. J'ai vu différentes versions de la façon de le configurer. Je ne sais pas si je dois mettre cela sous activemodel ou activeecord. J'ai pensé à activemodel puisque c'est là que se trouve le message personnalisé que je veux traduire.

Toute aide serait appréciée. C'est la dernière pièce que je dois régler avant de lancer ma première traduction de l'application.

MISE À JOUR 7/29/2013 7:30 pm CDT

bgates m'a donné un très bon départ sur la façon de configurer mes fichiers modèles pour recevoir le message personnalisé dans le fichier YAML. Cependant, j'ai fini par devoir faire la configuration suivante dans mon fichier YAML pour que les messages personnalisés soient trouvés.

activerecord:
  errors: 
    models: 
      user: 
        attributes: 
          bio: 
            no_links: "cannot contain email addresses or website links (URLs)."
          email: 
            bad_email: "is not a valid email address format."
          username: 
            bad_username: "can only contain numbers and letters.  No special characters or spaces."

87voto

bgates Points 2253

Utilisez un symbole pour le message :

validates :email, presence:   true, length: { maximum: 60 },
            format:     { with: valid_email_regex, message: :bad_email },
            uniqueness: { case_sensitive: false } 

puis dans le fichier yaml

[lang]:
  activerecord:
    errors:
      messages:
        bad_email: "just ain't right"

S'il existe une traduction spécifique à ce modèle, elle remplacera la traduction générale ci-dessus :

[lang]:
  activerecord:
    errors:
      models:
        model_name: # or namespace/model_name
          attributes:
            email:
              bad_email: "model-specific message for invalid email"

Si vous écrivez des validations personnalisées, add_error(:email, :bad_email) fera la recherche ci-dessus, mais errors[:email] << :bad_email ne le fera pas.

28voto

oma Points 5398

Je viens de traverser tout ça et j'ai trouvé le guides rails pour les validateurs personnalisés trop codé en dur... Je poste ceci ici même si ce n'est pas exactement ce que vous avez demandé, mais le titre de la Q correspond parfaitement (c'est pourquoi je lis ce post pour mon problème).

Validation personnalisée avec message i18n :

validate :something_custom?, if: :some_trigger_condition

def something_custom?
  if some_error_condition
    errors.add(:some_field_key, :some_custom_msg)
  end
end

# en.yml
activerecord: 
  errors:
    models:
      some_model:
        some_custom_msg: "This is i18n controlled. yay!"

3voto

BookOfGreg Points 1041

La solution à ce problème n'a pas besoin d'être personnalisée. format Le message du validateur correspond déjà au :invalid symbole. Il suffit de définir l'invalide en traduction.

en:
  activerecord:
    errors:
      models:
        some_model:
          attributes:
            email:
              invalid: "FOO"

Référence : http://edgeguides.rubyonrails.org/i18n.html#error-message-interpolation

1voto

Ruto Collins Points 875

Je vais vous donner un exemple complet.

Pour rendre vos modèles plus propres, vous peut créez une méthode d'aide à la validation personnalisée dans un tout nouveau répertoire. app/validations qui sera chargé automatiquement par Rails.

Je vais appeler mon dossier time_validator.rb situé à app/validations/time_validator.rb

Mon fichier contient le code suivant, qui valide l'heure saisie par l'utilisateur - qu'elle soit en fait temps.

# frozen_string_literal: true

class TimeValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    Time.parse(value).strftime('%H:%M')
  rescue ArgumentError 
    record.errors.add(attribute, :invalid_time)
  end
end

Vous pouvez en savoir plus sur la création de validations ActiveRecord personnalisées. aquí

Notre principal sujet de préoccupation est le record.errors ligne. Notez que c'est attribute et non :attributeattribute est la colonne dans votre modèle.

:invalid_time est la clé qui permet de récupérer le contenu traduit à partir de votre fichier locales. Dans mon cas, il s'agit de la clé en fichier :

en
  activerecord:
    errors:
      models:
        home:
          attributes:
            check_in_time:
              invalid_time: Please enter valid time
            check_out_time:
              invalid_time: Please enter valid time

Ensuite, dans le home modèle :

validates :check_in_time, time: { allow_blank: true }
validates :check_out_time, time: { allow_blank: true }

time est automatiquement affectée à la classe TimeValidator et les méthodes qu'il contient sont exécutées.

En cas de violation, ActiveRecord affichera une erreur juste en dessous du nom de la colonne.

J'espère que cela vous aidera !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X