Utilisation de Rails J'essaie d'obtenir un message d'erreur du type "Le champ de la chanson ne peut pas être vide" lors de la sauvegarde. 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 satisfaisant 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 réel du champ dans la base de données, mais j'ai plusieurs champs "chanson" et j'ai besoin d'avoir des noms de champs spécifiques.
Je ne veux pas pirater le processus de validation de Rails et j'estime qu'il devrait y avoir un moyen de résoudre ce problème.
Maintenant, le moyen accepté de définir les noms humanisés et les messages d'erreur personnalisés consiste à utiliser les paramètres régionaux .
# config/locales/en.yml
en:
activerecord:
attributes:
user:
email: "E-mail address"
errors:
models:
user:
attributes:
email:
blank: "is required"
Maintenant le nom humanisé et le message de validation de présence pour l'attribut "email" ont été modifiés.
Les messages de validation peuvent être définis pour un modèle spécifique + attribut, modèle, attribut ou globalement.
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 de l'attribut
address1 Put some address please
si vous voulez obtenir le message d'erreur pour un seul attribut
<%= @model.errors[:address1] %>
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é ceci ici .
Voici une autre façon de le faire ..___ Ce que vous faites est de définir une méthode human_attribute_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_attribute_name(attr)
HUMANIZED_ATTRIBUTES[attr.to_sym] || super
end
end
Le code ci-dessus est de ici
Oui, il existe un moyen de faire cela 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 ce soit Rails 3 (je ne sais pas si c'est différent dans les versions précédentes),
gardez ceci dans votre modèle:
validates_presence_of :song_rep_xyz, :message => "can't be empty"
et dans la vue, au lieu de quitter
@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 n'obtiendrez que le message que vous avez spécifié dans le modèle, sans le nom de l'attribut.
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 affichons un seul message, toujours pour la première erreur. Si vous voulez afficher toutes les erreurs, vous pouvez effectuer une boucle dans le hachage et afficher les valeurs.
J'espère que ça a aidé.
Dans la méthode de validation personnalisée, utilisez:
errors.add(:base, "Custom error message")
comme add_to_base est obsolète.
errors.add_to_base("Custom error message")
Rails3 Code avec des messages entièrement localisés:
Dans le modèle user.rb définir la validation
validates :email, :presence => true
Dans config/locales/en.yml
en:
activerecord:
models:
user: "Customer"
attributes:
user:
email: "Email address"
errors:
models:
user:
attributes:
email:
blank: "cannot be empty"
Je recommande d'installer le custom_error_message gem (ou en tant que plugin ) écrit à l'origine par David Easley
Cela vous permet de faire des choses comme:
validates_presence_of :non_friendly_field_name, :message => "^Friendly field name is blank"
En rapport avec les réponses acceptées _ et une autre réponse en bas de la liste :
Je confirme que la branche de nanamkim de custom-err-msg fonctionne avec Rails 5 et avec les paramètres régionaux.
Il vous suffit de commencer le message de paramètres régionaux avec un signe d'insertion et le nom d'attribut ne doit pas s'afficher 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:
attributes:
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
Voici un autre moyen:
Si vous utilisez ce modèle:
<% if @thing.errors.any? %>
<ul>
<% @thing.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
<% 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 manière, en raison 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 cet espace supplémentaire au début, ajoutez simplement la méthode .lstrip
.
<% if @thing.errors.any? %>
<ul>
<% @thing.errors.full_messages.each do |message| %>
<li><%= message.lstrip %></li>
<% end %>
</ul>
<% end %>
La méthode String.lstrip supprimera l'espace supplémentaire créé par ': _' et laissera tous 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_attribute.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 tel que "l'URL ne peut être vide", vous ne pouvez pas le faire. Au lieu de cela, essayez d’ajouter un autre mot comme clé:
def custom_validation_method_with_message
if some_model_attribute.blank?
errors.add(:the, "URL can't be blank")
end
end
Maintenant, le message complet sera "L'URL ne peut pas être vide"
Il suffit de le faire de manière normale:
validates_presence_of :email, :message => "Email is required."
Mais affichez-le comme ceci à la place
<% if @user.errors.any? %>
<% @user.errors.messages.each do |message| %>
<div class="message"><%= message.last.last.html_safe %></div>
<% end %>
<% end %>
Résultats
"Email is required."
La méthode de localisation est certainement le moyen "approprié" de le faire, mais si vous faites un petit projet non global et que vous voulez aller vite - c'est vraiment plus facile que de parcourir des fichiers.
Je l'aime pour la possibilité de mettre le nom du champ ailleurs que le début de la chaîne:
validates_uniqueness_of :email, :message => "There is already an account with that email."
Une solution pourrait être de changer le format d'erreur par défaut d'i18n:
en:
errors:
format: "%{message}"
La valeur par défaut est format: %{attribute} %{message}
Si vous voulez tous les lister dans une liste de Nice mais sans utiliser le nom sympathique et non humain, vous pouvez le faire.
object.errors.each do |attr,message|
puts "<li>"+message+"</li>"
end
À votre avis
object.errors.each do |attr,msg|
if msg.is_a? String
if attr == :base
content_tag :li, msg
elsif msg[0] == "^"
content_tag :li, msg[1..-1]
else
content_tag :li, "#{object.class.human_attribute_name(attr)} #{msg}"
end
end
end
Lorsque vous souhaitez remplacer le message d'erreur sans le nom de l'attribut, ajoutez simplement ^ comme suit le message:
validates :last_name,
uniqueness: {
scope: [:first_name, :course_id, :user_id],
case_sensitive: false,
message: "^This student has already been registered."
}
Voici mon code qui peut vous être utile si vous en avez 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éé un assistant 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
<div class="general-error alert show">
#{messages}
</div>
HTML
html.html_safe
end
def error_messages?
!resource.errors.empty?
end
end
J'ai essayé de suivre, a 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? %>
<h2>Errors</h2>
<ul>
<% @job.errors.full_messages.each do |message|%>
<li><%= message %></li>
<% end %>
</ul>
<% end %>
<div>
<%= f.label :title %>
<%= f.text_field :title %>
</div>
<div>
<%= f.label :description %>
<%= f.text_area :description, size: '60x6' %>
</div>
<div>
<%= f.submit %>
</div>
<% end %>
Une approche unique que je n'ai jamais vue mentionnée!
La seule façon dont j'ai pu obtenir toute la personnalisation que je souhaitais était d'utiliser un rappel after_validation
pour me permettre de manipuler le message d'erreur.
Pour que le message de validation soit créé normalement, vous n'avez pas besoin d'essayer de le modifier dans l'aide à la validation.
créez un callback after_validation
qui remplacera ce message de validation dans le back-end avant qu’il n’atteigne la vue.
Dans la méthode after_validation
, vous pouvez faire ce que vous voulez avec le message de validation, comme une chaîne normale! Vous pouvez même utiliser des valeurs dynamiques et les insérer dans le message de validation.
#this could be any validation
validates_presence_of :song_rep_xyz, :message => "whatever you want - who cares - we will replace you later"
after_validation :replace_validation_message
def replace_validation_message
custom_value = #any value you would like
errors.messages[:name_of_the_attribute] = ["^This is the replacement message where
you can now add your own dynamic values!!! #{custom_value}"]
end
La méthode after_validation aura une portée beaucoup plus grande que l'assistant de validation Rails intégré. Vous pourrez donc accéder à l'objet que vous validez comme vous essayez de le faire avec object.file_name. Ce qui ne fonctionne pas dans l'assistant de validation où vous essayez de l'appeler.
Remarque: nous utilisons le ^
pour supprimer le nom de l'attribut au début de la validation, comme l'a indiqué @Rystraum en faisant référence à ce gem
Si vous travaillez avec Rails-5, vous pouvez également utiliser les éléments suivants:
valide: nom d'utilisateur, présence: true, unicité: {message: "le nom d'utilisateur existe déjà."}