validator validations validate validar rails formularios formulario form ruby-on-rails

ruby on rails - validations - Mensaje de error de validación totalmente personalizado con Rails



validate form rails (16)

Uso de Rails Estoy intentando obtener un mensaje de error como "El campo de la canción no puede estar vacío" al guardar. Haciendo lo siguiente:

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

... solo muestra "Song Rep XYW no puede estar vacío", lo cual no es bueno porque el título del campo no es fácil de usar. ¿Cómo puedo cambiar el título del propio campo? Podría cambiar el nombre real del campo en la base de datos, pero tengo varios campos de "canción" y necesito tener nombres de campo específicos.

No quiero hackear el proceso de validación de los rieles y creo que debería haber una manera de solucionarlo.


Ahora, la forma aceptada de configurar los nombres humanizados y los mensajes de error personalizados es usar locales .

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

Ahora se han cambiado el nombre humanizado y el mensaje de validación de presencia para el atributo "correo electrónico".

Los mensajes de validación se pueden configurar para un modelo específico + atributo, modelo, atributo o globalmente.


Aquí está mi código que puede ser útil para usted en caso de que aún lo necesite: Mi modelo:

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

Entonces he creado un ayudante para mostrar mensajes:

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


Aquí hay otra manera:

Si usas esta plantilla:

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

Puedes escribir tu propio mensaje personalizado como este:

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 esta manera, debido al guión bajo, el mensaje completo se convierte en "Mi mensaje personalizado", pero el espacio adicional al principio es imperceptible. Si realmente no quieres ese espacio extra al principio solo agrega el método .lstrip .

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

El método String.lstrip eliminará el espacio adicional creado por '': _'' y dejará cualquier otro mensaje de error sin cambios.

O incluso mejor, use la primera palabra de su mensaje personalizado como clave:

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

Ahora el mensaje completo será "Mi mensaje personalizado" sin espacio adicional.

Si desea que el mensaje completo comience con una palabra en mayúscula como "La URL no puede estar en blanco", no se puede hacer. En su lugar, intente agregar alguna otra palabra como clave:

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

Ahora el mensaje completo será "La URL no puede estar en blanco"


Código Rails3 con mensajes totalmente localizados:

En el modelo user.rb se define la validación.

validates :email, :presence => true

En config / locales / en.yml

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


En el método de validación personalizado use:

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

como add_to_base ha quedado en desuso.

errors.add_to_base("Custom error message")


En su opinión

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

Cuando desee anular el mensaje de error sin el nombre del atributo, simplemente anteponga el mensaje con ^ así:

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


En tu modelo:

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

En su opinión

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

Si lo haces en su lugar

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

Obtienes este mensaje de error con el nombre del atributo

address1 Put some address please

Si desea obtener el mensaje de error para un solo atributo

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


Prueba esto.

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

Encontré esto here .

Aquí hay otra forma de hacerlo. Lo que hace es definir un método human_attribute_name en la clase del modelo. El método pasa el nombre de columna como una cadena y devuelve la cadena para usar en los mensajes de validación.

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

El código anterior es de here


Recomiendo instalar la gema custom_error_message (o como un plugin ) originalmente escrito por David Easley

Te permite hacer cosas como:

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


Relacionado con la respuesta aceptada y otra respuesta más abajo en la lista :

Estoy confirmando que github.com/nanamkim/custom-err-msg funciona con Rails 5 y con la configuración de la configuración regional.

Solo necesita iniciar el mensaje de configuración regional con un símbolo de intercalación y no debe mostrar el nombre del atributo en el mensaje.

Un modelo definido como:

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

con el siguiente en.yml :

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

item.errors.full_messages mostrará:

You can''t create an item without a name

en lugar del Name You can''t create an item without a name habitual Name You can''t create an item without a name


Sí, hay una manera de hacer esto sin el complemento! Pero no es tan limpio y elegante como usar el complemento mencionado. Aquí está.

Suponiendo que sea Rails 3 (no sé si es diferente en versiones anteriores),

mantén esto en tu modelo:

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

Y en la vista, en lugar de irse.

@instance.errors.full_messages

como lo sería cuando usemos el generador de andamio, ponemos:

@instance.errors.first[1]

Y obtendrá solo el mensaje que especificó en el modelo, sin el nombre del atributo.

Explicación:

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

Hasta ahora solo mostramos un mensaje, siempre para el primer error. Si desea mostrar todos los errores, puede hacer un bucle en el hash y mostrar los valores.

Espero que haya ayudado.


Si desea enumerarlos todos en una buena lista pero sin usar el nombre amigable no humano, puede hacer esto ...

object.errors.each do |attr,message| puts "<li>"+message+"</li>" end


Si está trabajando con Rails-5 también puede ir con lo siguiente:

valida: nombre_usuario, presencia: verdadero, singularidad: {mensaje: "El nombre de usuario ya existe."}


Solo hazlo de la manera normal:

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

Pero exhibirlo así en su lugar

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

Devoluciones

"Email is required."

El método de localización es definitivamente la forma "adecuada" de hacer esto, pero si está haciendo un pequeño proyecto no global y quiere comenzar rápidamente, esto es definitivamente más fácil que el salto de archivos.

Me gusta por la capacidad de poner el nombre del campo en otro lugar que no sea el principio de la cadena:

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


Traté de seguir, trabajé para mí :)

1 trabajo.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 %>


Una solución podría ser cambiar el formato de error predeterminado de i18n:

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

El format: %{attribute} %{message} predeterminado es format: %{attribute} %{message}