Vollständig benutzerdefinierte validationserrorsmeldung mit Rails

Rails verwenden Ich versuche beim Speichern eine Fehlermeldung wie “Das Song-Feld darf nicht leer sein” zu erhalten. Folgendes tun:

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

… zeigt nur “Song Rep. XYW kann nicht leer sein”, was nicht gut ist, weil der Titel des Feldes nicht benutzerfreundlich ist. Wie kann ich den Titel des Feldes selbst ändern? Ich könnte den tatsächlichen Namen des Feldes in der database ändern, aber ich habe mehrere “Lied” -Felder und ich muss spezifische Feldnamen haben.

Ich möchte nicht den validationsprozess der Rails hacken und ich denke, dass es einen Weg geben sollte, das zu beheben.

Die akzeptierte Möglichkeit zum Festlegen der personalisierten Namen und benutzerdefinierten Fehlermeldungen besteht nun in der Verwendung von Gebietsschemas .

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

Nun wurden der humanisierte Name und die Anwesenheitsvalidierungsnachricht für das Attribut “email” geändert.

validationsnachrichten können für ein bestimmtes Modell + Attribut, Modell, Attribut oder global festgelegt werden.

Versuche dies.

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

Ich habe das hier gefunden .

Hier ist ein anderer Weg, es zu tun. Sie definieren eine human_attribute_name-Methode für die Modellklasse. Der Methode wird der Spaltenname als Zeichenfolge übergeben und die in validationsnachrichten zu verwendende Zeichenfolge zurückgegeben.

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

Der obige Code ist von hier

In Ihrem Modell:

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

Aus Ihrer Sicht

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

Wenn Sie stattdessen tun

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

Sie erhalten diese Fehlermeldung mit dem Attributnamen

 address1 Put some address please 

wenn Sie die Fehlermeldung für ein einzelnes Attribut erhalten möchten

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

Ja, es gibt eine Möglichkeit, dies ohne das Plugin zu tun! Aber es ist nicht so sauber und elegant wie das erwähnte Plugin. Hier ist es.

Angenommen, es ist Rails 3 (ich weiß nicht, ob es in früheren Versionen anders ist),

behalte das in deinem Modell:

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

und in der Ansicht, anstatt zu verlassen

 @instance.errors.full_messages 

wie es wäre, wenn wir den Gerüstgenerator verwenden würden:

 @instance.errors.first[1] 

Und Sie erhalten nur die Nachricht, die Sie im Modell angegeben haben, ohne den Attributnamen.

Erläuterung:

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

Bisher zeigen wir nur eine Nachricht an, immer für den ersten Fehler. Wenn Sie alle Fehler anzeigen möchten, können Sie den Hash wiederholen und die Werte anzeigen.

Hoffnung, die geholfen hat.

Rails3 Code mit vollständig lokalisierten Nachrichten:

Definieren Sie im Modell user.rb die validation

 validates :email, :presence => true 

In config / locales / en.yml

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

Verwenden Sie in der benutzerdefinierten Überprüfungsmethode:

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

als add_to_base ist veraltet.

errors.add_to_base("Custom error message")

Ich empfehle, das Juwel custom_error_message (oder als Plugin ) zu installieren, das ursprünglich von David Easley geschrieben wurde

Sie können Dinge tun wie:

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

Bezogen auf die angenommene Antwort und eine andere Antwort in der Liste :

Ich bestätige, dass nanamkims Fork von custom-err-msg mit Rails 5 und dem Gebietsschema funktioniert.

Sie müssen nur die Gebietsschema-Nachricht mit einem Caret starten und es sollte den Attributnamen in der Nachricht nicht anzeigen.

Ein Modell definiert als:

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

mit dem folgenden en.yml :

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

item.errors.full_messages wird angezeigt:

 You can't create an item without a name 

anstelle des üblichen Name You can't create an item without a name

Mach es einfach so:

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

Aber zeige es stattdessen so an

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

Kehrt zurück

 "Email is required." 

Die Lokalisierungsmethode ist definitiv der “richtige” Weg, um dies zu tun, aber wenn Sie ein kleines, nicht-globales Projekt machen und einfach schnell loslegen wollen – das ist definitiv einfacher als Datei-Hopping.

Ich mag es für die Fähigkeit, den Feldnamen irgendwo anders als den Anfang der Zeichenfolge zu setzen:

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

Hier ist ein anderer Weg:

Wenn Sie diese Vorlage verwenden:

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

Sie können Ihre eigene benutzerdefinierte Nachricht wie folgt schreiben:

 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 

Auf diese Weise wird die vollständige Nachricht aufgrund der Unterstreichung "Meine benutzerdefinierte Nachricht", aber der zusätzliche Speicherplatz am Anfang ist nicht bemerkbar. Wenn Sie diesen zusätzlichen Platz am Anfang nicht wirklich benötigen, fügen .lstrip einfach die .lstrip Methode hinzu.

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

Die String.lstrip-Methode wird den zusätzlichen Speicherplatz, der von ': _' erstellt wurde, entfernen und alle anderen Fehlermeldungen unverändert lassen.

Oder noch besser, verwenden Sie das erste Wort Ihrer benutzerdefinierten Nachricht als Schlüssel:

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

Jetzt lautet die vollständige Nachricht "Meine benutzerdefinierte Nachricht" ohne zusätzlichen Speicherplatz.

Wenn Sie möchten, dass die vollständige Nachricht mit einem Großbuchstaben wie "URL darf nicht leer sein" beginnt, kann sie nicht ausgeführt werden. Versuchen Sie stattdessen, ein anderes Wort als Schlüssel hinzuzufügen:

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

Jetzt lautet die vollständige Nachricht "Die URL darf nicht leer sein"

Eine Lösung könnte darin bestehen, das i18n-Standarderrorsformat zu ändern:

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

Standard ist das format: %{attribute} %{message}

Wenn Sie sie alle in einer netten Liste auflisten möchten, aber ohne den nicht menschlich freundlichen Namen zu verwenden, können Sie dies tun …

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

    Aus Ihrer Sicht

     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 

    Wenn Sie die Fehlermeldung ohne den Attributnamen überschreiben möchten, fügen Sie die Nachricht einfach mit ^ voran:

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

    Ich habe versucht, zu folgen, arbeitete für mich 🙂

    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 %>

    Hier ist mein Code, der für Sie nützlich sein kann, falls Sie ihn noch brauchen: Mein Modell:

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

    Dann habe ich einen Helfer zum Anzeigen von Nachrichten erstellt:

     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