Message d’erreur de validation entièrement personnalisé avec Rails

Utilisation de Rails J’essaie d’obtenir un message d’erreur tel que “Le champ de la chanson ne peut pas être vide” lors de l’enregistrement. Faire ce qui suit:

validates_presence_of :song_rep_xyz, :message => "can't be empty" 

… affiche uniquement “Song Rep XYW ne peut pas être vide”, ce qui n’est pas bon car le titre du champ n’est pas convivial. Comment puis-je changer le titre du champ lui-même? Je pourrais changer le nom actuel du champ dans la firebase database, mais j’ai plusieurs champs de “chanson” et je dois avoir des noms de champs spécifiques.

Je ne veux pas contourner le processus de validation des rails et j’estime qu’il devrait y avoir un moyen d’y remédier.

Désormais, la méthode acceptée pour définir les noms humanisés et les messages d’erreur personnalisés consiste à utiliser les parameters régionaux .

 # config/locales/en.yml en: activerecord: atsortingbutes: user: email: "E-mail address" errors: models: user: atsortingbutes: email: blank: "is required" 

Maintenant, le nom humanisé et le message de validation de la présence de l’atsortingbut “email” ont été modifiés.

Les messages de validation peuvent être définis pour un modèle spécifique + atsortingbut, modèle, atsortingbut ou globalement.

Essaye ça.

 class User < ActiveRecord::Base validate do |user| user.errors.add_to_base("Country can't be blank") if user.country_iso.blank? end end 

J'ai trouvé ça ici .

Voici une autre façon de le faire. Vous définissez une méthode human_atsortingbute_name sur la classe de modèle. Le nom de la colonne est transmis à la méthode sous forme de chaîne et renvoie la chaîne à utiliser dans les messages de validation.

 class User < ActiveRecord::Base HUMANIZED_ATTRIBUTES = { :email => "E-mail address" } def self.human_atsortingbute_name(attr) HUMANIZED_ATTRIBUTES[attr.to_sym] || super end end 

Le code ci-dessus est d' ici

Dans votre modèle:

 validates_presence_of :address1, :message => "Put some address please" 

À votre avis

 < % m.errors.each do |attr,msg| %> < %=msg%> < % end %> 

Si vous faites plutôt

 < %=attr %> < %=msg %> 

vous obtenez ce message d’erreur avec le nom d’atsortingbut

 address1 Put some address please 

si vous voulez obtenir le message d’erreur pour un seul atsortingbut

 < %= @model.errors[:address1] %> 

Oui, il y a un moyen de le faire sans le plugin! Mais ce n’est pas aussi propre et élégant que d’utiliser le plugin mentionné. C’est ici.

En supposant que c’est Rails 3 (je ne sais pas si c’est différent dans les versions précédentes),

garde ça dans ton modèle:

 validates_presence_of :song_rep_xyz, :message => "can't be empty" 

et dans la vue, au lieu de partir

 @instance.errors.full_messages 

comme ce serait le cas lorsque nous utilisons le générateur d’échafaudage, mettez:

 @instance.errors.first[1] 

Et vous obtiendrez juste le message que vous avez spécifié dans le modèle, sans le nom d’atsortingbut.

Explication:

 #returns an hash of messages, one element foreach field error, in this particular case would be just one element in the hash: @instance.errors # => {:song_rep_xyz=>"can't be empty"} #this returns the first element of the hash as an array like [:key,"value"] @instance.errors.first # => [:song_rep_xyz, "can't be empty"] #by doing the following, you are telling ruby to take just the second element of that array, which is the message. @instance.errors.first[1] 

Jusqu’à présent, nous ne montrons qu’un seul message, toujours pour la première erreur. Si vous voulez afficher toutes les erreurs, vous pouvez faire une boucle dans le hachage et afficher les valeurs.

J’espère que ça a aidé.

Code Rails3 avec des messages entièrement localisés:

Dans le modèle user.rb, définissez la validation

 validates :email, :presence => true 

Dans config / locales / en.yml

 en: activerecord: models: user: "Customer" atsortingbutes: user: email: "Email address" errors: models: user: atsortingbutes: email: blank: "cannot be empty" 

Dans la méthode de validation personnalisée, utilisez:

errors.add(:base, "Custom error message")

comme add_to_base a été déconseillé.

errors.add_to_base("Custom error message")

Je recommande d’installer le gem custom_error_message (ou un plugin ) écrit à l’origine par David Easley

Il vous permet de faire des choses comme:

 validates_presence_of :non_friendly_field_name, :message => "^Friendly field name is blank" 

En rapport avec la réponse acceptée et une autre réponse en bas de la liste :

Je confirme que le fork de nanamkim de custom-err-msg fonctionne avec Rails 5, et avec la configuration des parameters régionaux.

Il vous suffit de lancer le message de parameters régionaux avec un caret et il ne doit pas afficher le nom de l’atsortingbut dans le message.

Un modèle défini comme:

 class Item < ApplicationRecord validates :name, presence: true end 

avec le en.yml suivant:

 en: activerecord: errors: models: item: atsortingbutes: name: blank: "^You can't create an item without a name." 

item.errors.full_messages affichera:

 You can't create an item without a name 

au lieu du Name You can't create an item without a name habituel Name You can't create an item without a name

Faites-le comme d’habitude:

 validates_presence_of :email, :message => "Email is required." 

Mais affichez-le plutôt comme ça

 < % if @user.errors.any? %> < % @user.errors.messages.each do |message| %> 
< %= message.last.last.html_safe %>
< % end %> < % end %>

Résultats

 "Email is required." 

La méthode de localisation est sans aucun doute la manière “appropriée” de faire cela, mais si vous faites un petit projet non global et que vous voulez simplement aller vite – c’est plus facile que le saut de fichier.

Je l’aime pour la possibilité de mettre le nom du champ quelque part autre que le début de la chaîne:

 validates_uniqueness_of :email, :message => "There is already an account with that email." 

Voici une autre façon:

Si vous utilisez ce modèle:

 < % if @thing.errors.any? %> 
    < % @thing.errors.full_messages.each do |message| %>
  • < %= message %>
  • < % end %>
< % end %>

Vous pouvez écrire votre propre message personnalisé comme ceci:

 class Thing < ActiveRecord::Base validate :custom_validation_method_with_message def custom_validation_method_with_message if some_model_attribute.blank? errors.add(:_, "My custom message") end end 

De cette façon, à cause du trait de soulignement, le message complet devient "Mon message personnalisé", mais l'espace supplémentaire au début est imperceptible. Si vous ne voulez vraiment pas de cet espace supplémentaire au début, ajoutez simplement la méthode .lssortingp .

 < % if @thing.errors.any? %> 
    < % @thing.errors.full_messages.each do |message| %>
  • < %= message.lstrip %>
  • < % end %>
< % end %>

La méthode Ssortingng.lssortingp supprimera l'espace supplémentaire créé par ': _' et laissera les autres messages d'erreur inchangés.

Ou mieux encore, utilisez le premier mot de votre message personnalisé comme clé:

  def custom_validation_method_with_message if some_model_atsortingbute.blank? errors.add(:my, "custom message") end end 

Maintenant, le message complet sera "Mon message personnalisé" sans espace supplémentaire.

Si vous souhaitez que le message complet commence par un mot en majuscule comme "URL ne peut pas être vide", cela ne peut pas être fait. Essayez plutôt d'append un autre mot comme clé:

  def custom_validation_method_with_message if some_model_atsortingbute.blank? errors.add(:the, "URL can't be blank") end end 

Maintenant, le message complet sera "L'URL ne peut pas être vide"

Une solution pourrait être de changer le format d’erreur par défaut de i18n:

 en: errors: format: "%{message}" 

Le format: %{atsortingbute} %{message} par défaut est format: %{atsortingbute} %{message}

Si vous voulez tous les lister dans une belle liste mais sans utiliser le nom cruddy non humain, vous pouvez le faire …

 object.errors.each do |attr,message| puts "
  • "+message+"
  • " end

    À votre avis

     object.errors.each do |attr,msg| if msg.is_a? Ssortingng if attr == :base content_tag :li, msg elsif msg[0] == "^" content_tag :li, msg[1..-1] else content_tag :li, "#{object.class.human_atsortingbute_name(attr)} #{msg}" end end end 

    Lorsque vous voulez remplacer le message d’erreur sans le nom de l’atsortingbut, ajoutez simplement le message avec ^ comme ceci:

     validates :last_name, uniqueness: { scope: [:first_name, :course_id, :user_id], case_sensitive: false, message: "^This student has already been registered." } 

    J’ai essayé de suivre, travaillé pour moi 🙂

    1 job.rb

     class Job < ApplicationRecord validates :description, presence: true validates :title, :presence => true, :length => { :minimum => 5, :message => "Must be at least 5 characters"} end 

    2 jobs_controller.rb

     def create @job = Job.create(job_params) if @job.valid? redirect_to jobs_path else render new_job_path end end 

    3 _form.html.erb

     < %= form_for @job do |f| %> < % if @job.errors.any? %> 

    Errors

      < % @job.errors.full_messages.each do |message|%>
    • < %= message %>
    • < % end %>
    < % end %>
    < %= f.label :title %> < %= f.text_field :title %>
    < %= f.label :description %> < %= f.text_area :description, size: '60x6' %>
    < %= f.submit %>
    < % end %>

    Voici mon code qui peut vous être utile au cas où vous en auriez encore besoin: Mon modèle:

     validates :director, acceptance: {message: "^Please confirm that you are a director of the company."}, on: :create, if: :is_director? 

    Ensuite, j’ai créé une aide pour afficher les messages:

     module ErrorHelper def error_messages! return "" unless error_messages? messages = resource.errors.full_messages.map { |msg| if msg.present? && !msg.index("^").nil? content_tag(:p, msg.slice((msg.index("^")+1)..-1)) else content_tag(:p, msg) end }.join html = < <-HTML 
    #{messages} HTML html.html_safe end def error_messages? !resource.errors.empty? end end