W pełni niestandardowy komunikat o błędzie walidacji za pomocą Rails
Używając Rails próbuję uzyskać komunikat o błędzie, taki jak" Pole piosenki nie może być puste " w save. Wykonanie:
validates_presence_of :song_rep_xyz, :message => "can't be empty"
... wyświetla tylko "Song Rep XYW can 't be empty" , co nie jest dobre, ponieważ tytuł pola nie jest przyjazny dla użytkownika. Jak Mogę zmienić tytuł samego pola ? Mógłbym zmienić rzeczywistą nazwę pola w bazie danych, ale mam wiele pól "piosenki" i muszę mieć konkretne nazwy pól.
Nie chcę się włamywać po railach' proces walidacji i uważam, że powinien być sposób, aby to naprawić.
15 answers
Obecnie akceptowanym sposobem ustawiania humanizowanych nazw i niestandardowych komunikatów o błędach jest użycie locales .
# config/locales/en.yml
en:
activerecord:
attributes:
user:
email: "E-mail address"
errors:
models:
user:
attributes:
email:
blank: "is required"
Teraz humanizowana nazwa i wiadomość potwierdzająca obecność dla atrybutu "email" zostały zmienione.
Komunikaty walidacji mogą być ustawione dla określonego modelu+atrybut, model, atrybut lub globalnie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-17 16:30:24
W twoim modelu:
validates_presence_of :address1, :message => "Put some address please"
In your view
<% m.errors.each do |attr,msg| %>
<%=msg%>
<% end %>
If you do instead
<%=attr %> <%=msg %>
Pojawia się komunikat o błędzie z nazwą atrybutu
address1 Put some address please
Jeśli Chcesz otrzymać komunikat o błędzie dla jednego atrybutu
<%= @model.errors[:address1] %>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-27 03:50:45
Spróbuj tego.
class User < ActiveRecord::Base
validate do |user|
user.errors.add_to_base("Country can't be blank") if user.country_iso.blank?
end
end
Znalazłem to tutaj .
Oto inny sposób, aby to zrobić. To, co robisz, to definiowanie metody human_attribute_name na klasie modelu. Metoda przekazuje nazwę kolumny jako łańcuch znaków i zwraca łańcuch znaków do wykorzystania w komunikatach sprawdzania poprawności.
class User < ActiveRecord::Base
HUMANIZED_ATTRIBUTES = {
:email => "E-mail address"
}
def self.human_attribute_name(attr)
HUMANIZED_ATTRIBUTES[attr.to_sym] || super
end
end
Powyższy kod pochodzi z tutaj
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-01 13:28:38
Tak, jest sposób, aby to zrobić bez wtyczki! Ale nie jest tak czysty i elegancki jak korzystanie z wspomnianej wtyczki. Tutaj jest.
Zakładając, że to Rails 3 (Nie wiem czy w poprzednich wersjach jest inaczej),
Zachowaj to w swoim modelu:
validates_presence_of :song_rep_xyz, :message => "can't be empty"
I w widoku, zamiast zostawić
@instance.errors.full_messages
Jak by było, gdy użyjemy generatora rusztowania, umieść:
@instance.errors.first[1]
I otrzymasz tylko wiadomość określoną w modelu, bez atrybutu nazwisko.
Wyjaśnienie:
#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]
Do tej pory wyświetlamy tylko jeden komunikat, zawsze dla pierwszego błędu. Jeśli chcesz wyświetlić wszystkie błędy, możesz zapętlić hash i pokazać wartości.
Mam nadzieję, że to pomogło.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-18 15:33:04
Kod Rails3 z w pełni zlokalizowanymi komunikatami:
W modelu użytkownika.rb define the validation
validates :email, :presence => true
W config / locales / en.yml
en:
activerecord:
models:
user: "Customer"
attributes:
user:
email: "Email address"
errors:
models:
user:
attributes:
email:
blank: "cannot be empty"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-18 13:34:15
W niestandardowej metodzie walidacji użyj:
errors.add(:base, "Custom error message")
Jako że add_to_base jest przestarzałe.
errors.add_to_base("Custom error message")
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-17 12:40:09
Zalecam zainstalowanie custom_error_message gem (lub jako plugin) pierwotnie napisany przez Davida Easleya
Pozwala robić takie rzeczy jak:
validates_presence_of :non_friendly_field_name, :message => "^Friendly field name is blank"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-01 08:02:51
Związane z zaakceptowaną odpowiedzią i kolejna odpowiedź na liście :
Potwierdzam, że widelec nanamkim z custom-err-msg działa z Rails 5 i z ustawieniami lokalnymi.
Wystarczy uruchomić wiadomość locale za pomocą karetki i nie powinna ona wyświetlać nazwy atrybutu w wiadomości.
Model zdefiniowany jako:
class Item < ApplicationRecord
validates :name, presence: true
end
Z następującym en.yml
:
en:
activerecord:
errors:
models:
item:
attributes:
name:
blank: "^You can't create an item without a name."
item.errors.full_messages
wyświetli:
You can't create an item without a name
Zamiast zwykłe Name You can't create an item without a name
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:28
Po prostu zrób to w normalny sposób:
validates_presence_of :email, :message => "Email is required."
Ale wyświetl to tak zamiast
<% if @user.errors.any? %>
<% @user.errors.messages.each do |message| %>
<div class="message"><%= message.last.last.html_safe %></div>
<% end %>
<% end %>
Zwraca
"Email is required."
Metoda lokalizacji jest zdecydowanie "właściwym" sposobem, aby to zrobić, ale jeśli robisz mały, Nie-globalny projekt i chcesz po prostu zacząć działać szybko - jest to zdecydowanie łatwiejsze niż przeskakiwanie plików.
Lubię to za możliwość umieszczenia nazwy pola gdzieś indziej niż początek łańcucha:
validates_uniqueness_of :email, :message => "There is already an account with that email."
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-24 14:26:12
Oto inny sposób:
Jeśli użyjesz tego szablonu:
<% if @thing.errors.any? %>
<ul>
<% @thing.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
<% end %>
Możesz napisać własną wiadomość tak:
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
W ten sposób, z powodu podkreślenia, pełna wiadomość staje się "moją niestandardową wiadomością", ale dodatkowa przestrzeń na początku jest niezauważalna. Jeśli naprawdę nie chcesz tej dodatkowej przestrzeni na początku, po prostu Dodaj metodę .lstrip
.
<% if @thing.errors.any? %>
<ul>
<% @thing.errors.full_messages.each do |message| %>
<li><%= message.lstrip %></li>
<% end %>
</ul>
<% end %>
Ciąg.metoda lstrip pozbędzie się dodatkowego miejsca utworzonego przez': _ ' i pozostawi wszelkie inne błędy wiadomości bez zmian.
A nawet lepiej, użyj pierwszego słowa niestandardowej wiadomości jako klucza: def custom_validation_method_with_message
if some_model_attribute.blank?
errors.add(:my, "custom message")
end
end
Teraz pełna wiadomość będzie "moja niestandardowa wiadomość" bez dodatkowego miejsca.
Jeśli chcesz, aby pełna wiadomość zaczynała się od słowa pisanego wielką literą, np. "URL can' t be blank", nie można tego zrobić. Zamiast tego spróbuj dodać inne słowo jako klucz:
def custom_validation_method_with_message
if some_model_attribute.blank?
errors.add(:the, "URL can't be blank")
end
end
Teraz pełna wiadomość będzie brzmiała "URL nie może być pusty"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-29 20:48:00
Jednym z rozwiązań może być zmiana domyślnego formatu błędu i18n:
en:
errors:
format: "%{message}"
Domyślnie jest to format: %{attribute} %{message}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-22 23:21:03
Jeśli chcesz umieścić je wszystkie na ładnej liście, ale bez używania szorstkiej, nie przyjaznej człowiekowi nazwy, możesz to zrobić...
object.errors.each do |attr,message|
puts "<li>"+message+"</li>"
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-23 15:05:28
In your view
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
Jeśli chcesz nadpisać komunikat o błędzie bez nazwy atrybutu, po prostu poprzedź go znakiem ^ w ten sposób:
validates :last_name,
uniqueness: {
scope: [:first_name, :course_id, :user_id],
case_sensitive: false,
message: "^This student has already been registered."
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-13 16:07:40
Próbowałem śledzić, pracował dla mnie:)
1 zadanie.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 %>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-03 23:08:35
Oto Mój kod, który może być dla Ciebie przydatny, jeśli nadal go potrzebujesz: Mój model:
validates :director, acceptance: {message: "^Please confirm that you are a director of the company."}, on: :create, if: :is_director?
Następnie stworzyłem helpera do wyświetlania wiadomości:
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-02 11:01:08