Validación básica en Rails 4 – mensajes en formulario

Al enviar dValidación básica en Rails 4atos desde un formulario se vuelve necesario validar los datos antes de guardarlos, Rails ofrece los mecanismos suficientes para realizar la validación del modelo que va desde un aspecto básico para aquellos que vamos empezando con este Framework hasta la implementación de validaciones que pueden parecernos complejas, pero leyendo un poco seguramente iremos aprendiendo a hacer algo que puede sorprendernos a nosotros mismos.

En este tutorial se explica como se mostrarían los mensajes de errores en los elementos del formulario que pudiera devolver el controlador al momento de realizar la validación de los datos enviados, esta forma no es AJAX, sino que requerirá que el usuario presione el botón Create para que entre en funcionamiento la validación, se que pueden existir tutoriales quizá con características más avanzadas, pero para lo que estaba buscando que es precisamente mostrar el mensaje de error por campo, no había localizado una buena fuente 😀 así que me dí a la tarea un rato de buscar una forma.

¿qué necesito saber?

¿dónde empiezo?

Para el demo, tenemos un modelo Client, y un controlador ClientController.

En el modelo Client, solo se agregó una validación de datos requeridos, por lo que el código se modificó a:

class Client < ActiveRecord::Base
  has_many :sales
  validates :nombre, :email, :presence => { message: "No puede dejarse vacío" }
end

En el controlador ClientsController, específicamente en la acción create se agregó una condición if @client.valid? , para que en caso de no ser válido, se redireccione a la acción new.

 # POST /clients
 # POST /clients.json
 def create
   @client = Client.new(client_params)
   respond_to do |format|
     if @client.valid? 
       if @client.save
         format.html { redirect_to @client, notice: 'Client was successfully created.' }
         format.json { render :show, status: :created, location: @client }
       else
         format.html { render :new }
         format.json { render json: @client.errors, status: :unprocessable_entity }
       end
     else
       format.html { render :new }
       format.json { render json: @client.errors, status: :unprocessable_entity }
     end
   end
 end

 

Modificación del formulario views/clients/_form.html.erb

En los ejemplos generales para mostrar los errores encontramos algo similar al este código que se agrega por encima de los campos del formulario:

<% if @client.errors.any? %>
 <div id="error_explanation">
  <ul>
   <% @client.errors.full_messages.each do |message| %>
   <li><%= message %></li>
   <% end %>
  </ul>
 </div>
<% end %>

Que al entrar en funcionamiento si aún no se ha agregado ningún tema o framework front-end vemos algo como esto:

Pero como en este ejemplo ya se ha agregado Bootstrap, el resultado se aprecia como:

sc2

 

 

 

 

 

Entonces con la modificación adecuada haremos que el mensaje de erro se muestre en el campo correspondiente.

Para cada etiqueta y campo, el código del ejemplo originalmente está como:

 <div class="control-group">
   <%= f.label :nombre, :class => 'control-label' %>
   <div class="controls">
     <%= f.text_field :nombre, :class => 'text_field' %>
   </div>
 </div>

Bootstrap contiene un estilo .error que hace que los elementos contenidos se muestren en color rojo, este estilo debe agregarse al <div class=”control-group”> para quedar como <div class=”control-group error“>

pero ¿cómo hacemos para que se agregue este estilo si y sólo si existe un error en este atributo (:nombre)?

Utilizaremos una expresión ternaria para comprobar si el atributo tiene un error.

En la sección 7 mencionada, rails explica que para comprobar los errores de un atributo, se realiza de la forma

@object.errors[:attribute].any?

Entonces para nuestro propósito, el código para generar el div quedará como:

<div class="control-group<%= @client.errors[:nombre].any? ? " error" : "" %>">

Esto dice: crear un div con el estilo control-group,  si existen errores para el atributo nombre entonces imprimir la cadena error, sino imprimir vacío(no se asigna el estilo error).

sc3

 

 

 

 

Ahora para mostrar el mensaje, agregaremos un span después del text field. En este span agregaremos nuevamente una expresion ternaria para comprobar si el atributo contiene error, entonces mostrar el mensaje.

 <span class="help-inline">
 <%= @client.errors[:nombre].any? ? @client.errors[:nombre].to_s[/\w([^"]*)/] : "" %></span>

Si nos preguntamos ¿por qué @client.errors[:nombre].to_s[/\w([^”]*)/]  ?

Para obtener el mensaje de error de un atributo se utiliza: @object.errors[:attibute]

Si quitamos la expresión regular [/\w([^”]*)/] obtendremos en pantalla el mensaje: [“No puede dejarse vacío”] con corchetes y comillas. Por lo que es necesario agregar una expresión regular para recuperar solo la cadena que empiece por una letra o número sin incluir las comillas.

El fragmento de código para el campo nombre:

 <div class="control-group<%= @client.errors[:nombre].any? ? " error" : "" %>">
   <%= f.label :nombre, :class => 'control-label' %>
   <div class="controls">
     <%= f.text_field :nombre, :class => 'text_field' %>
     <%#Obtener solo el mensaje con la expresion regular /\w([^]*)/%>
     <span class="help-inline">
      <%= @client.errors[:nombre].any? ? @client.errors[:nombre].to_s[/\w([^"]*)/] : "" %></span>
   </div>
 </div>

Lo mismo debe aplicarse para el resto de los campos que tienen validación.

Al presionar el botón Create y tener como resultado errores por causa de validación, nuestro formulario mostrará los mensajes en cada campo.

sc5

 

 

 

 

 

 

 

 

sc6

 

 

 

 

 

 

 

 

El código del ejemplo se encuentra disponible en: https://github.com/afelipelc/DemoRailsVentas/

 

Anuncios

Escribe tu comentario:

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s