web-dev-qa-db-fra.com

Ruby on Rails i18n - Vous voulez traduire des messages personnalisés dans les modèles

J'ai des attributs avec validation spéciale où j'utilise la clause message pour afficher un message spécial uniquement 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 le faire.

J'ai vu des exemples où ils tapent quelque chose comme ceci: message: t ("some_value_here"). Je ne suis pas sûr de la désignation. J'ai essayé quelque chose comme ce 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 eu l'erreur suivante:

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

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

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

J'ai fait des recherches à ce sujet par intermittence toute la journée. Tout ce que je peux trouver, c'est de remplacer les hachages d'erreur intégrés, vierges ou vierges. Existe-t-il un moyen pour moi d'avoir des hachages d'erreur personnalisés et de les remplacer dans le modèle? À ce stade, je ne peux pas obtenir le t de fonctionner comme codé. J'espère que le problème est de savoir comment mon fichier yaml est configuré. J'ai vu différentes versions de la façon de le configurer. Je ne sais pas si je devrais mettre cela sous activemodel ou activerecord. J'ai supposé activemodel puisque c'est là que le message personnalisé est que je veux traduire.

Toute aide serait appréciée. C'est le dernier élément que je dois comprendre avant de lancer ma première traduction de l'application.

MISE À JOUR 7/29/2013 19h30 HAC

bgates m'a donné un très bon début avec la façon de configurer mes fichiers de modèle pour recevoir le message personnalisé dans le fichier YAML. Cependant, j'ai fini par avoir à effectuer 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."

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, celle-ci 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) effectuera la recherche ci-dessus, mais errors[:email] << :bad_email ne le fera pas.

68
bgates

Je viens de parcourir tout cela et de trouver les guides Rails pour les validateurs personnalisés trop codés en dur ... Je publie cela ici même si ce n'est pas exactement ce que vous avez demandé, mais le titre Q convient parfaitement (c'est pourquoi J'ai lu 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!"
21
oma

La solution à ce problème n'a pas besoin d'être personnalisée; Le message du validateur format correspond déjà au symbole :invalid. Vous devez uniquement définir l'invalide dans la traduction.

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

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

2
BookOfGreg

Je vais donner un exemple complet.

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

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

Mon fichier a le code suivant, qui valide le temps saisi par l’utilisateur - qu’il s’agit du temps réellement.

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

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

:invalid_time est la clé qui extrait le contenu traduit de votre fichier de paramètres régionaux. Dans mon cas, il s’agit du fichier en:

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

Puis dans le modèle home:

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

time est automatiquement mappé à la classe TimeValidator et ses méthodes sont exécutées.

En cas d'infraction, ActiveRecord renvoie une erreur juste en dessous du nom de la colonne.

J'espère que cela t'aides!

0
Ruto Collins