Ruby on Rails es un framework con opinión: dar por hechas una serie de convenciones (convenciones con mucha lógica y sentido, por otro lado) para ahorrarnos esfuerzo en tareas repetitivas.

Así pues, una de esos "supuestos" es que todo formulario va a estar asociado a un modelo de datos, y por tanto será tratado por ActiveRecord, en el cuál se incluyen unos fantásticos validadores de datos. Dichos validadores son realmente sencillos de utilizar, muy intuitivos y potentes a la vez.

Por ejemplo:

RUBY:
  1. class MyClass <ActiveRecord::Base
  2.   ...
  3.   # validar que el campo title no sea nulo
  4.   validates_presence_of :title
  5.  
  6.   # validar que status toma sólo los valores "public" o "private"
  7.   validates_inclusion_of :status , :in => %w{ public private }
  8.  
  9.   # validar que la longitud del campo title esté entre 1 y 255 caracteres
  10.   validates_length_of :title, :in => 1..255
  11.   ...
  12. end

Pero claro, ¿qué hacemos cuando queremos validar un formulario que no esté asociado a un modelo de datos?, es decir, cuando no podamos declarar los validadores en clases que heredan de ActiveRecord, sino que los estemos usando como controladores.

La solución que he encontrado es realmente sencilla y elegante (no como la que había encontrado anteriormente en el wiki): consiste en utilizar el plugin Validator, que permite declarar un validador de ActiveRecord dentro de un controlador y utilizar la misma sintaxis que utilizaríamos en el modelo:

RUBY:
  1. # Función que valida los datos del formulario
  2. def validar_formulario(params)
  3.   validator = ActiveRecord::Validations::Validator.new(params)
  4.   validator.validate_with(:nombre, :filled => true)
  5.   validator.validate_with(:email, :format => /^([a-zA-Z0-9])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-]+)+/)
  6.   return true if validator.errors.empty?
  7.   return validator.errors
  8. end
  9.  
  10. def enviar_formulario
  11.   errores = validar_formulario(params)
  12.   # Si encontramos errores
  13.   if not errores == true
  14.     flash['alert'] = "Se han encontrado los siguientes problemas:<ul>"
  15.     # Añadimos los mensajes de error al flash['alert']
  16.     errores.each { |a,v|
  17.       flash['alert']+= "<li>#{v}</li>"
  18.     }
  19.     flash['alert']+="</ul>"
  20.     return
  21.   end
  22.    ....
  23. end

Limpio y claro.

Por supuesto, cualquier mejora o sugerencia será bienvenida y bien recibida.


13 Comentarios en “Validación de datos en controladores sin modelo asociado con Ruby on Rails”  

  1. Gravatar Icon 1 Aníbal Rojas

    Interesante… después reviso el código con más clama que es taaaaarde y tengo los ojos cuadrados de tanto ver el monitor. Saludos.

  2. Gravatar Icon 2 Senseixon

    Yo tengo graves problemas con rails…
    :(

    Me cuesta mucho definir la sintaxi.
    ¿¿Cómo puedo poner un condicionante en el controlador para que reciba o no una variable??

    ufff… parece estar muy bien RoR pero no se si puedo llegar a aprenderlo… ¿alguna ayudita?
    gracias de todos modos

    y saludos !!!!

  3. Gravatar Icon 3 Fernando

    Hola Senseixon,

    no entiendo muy bien tu pregunta, así que te recomiendo que te des de alta en la lista de Rails en castellano: http://lists.simplelogica.net/mailman/listinfo/ror-es

  4. Gravatar Icon 4 sergio

    hola tengo una duda para validar un formulario donde si ingreso letra por numero me tire una error o al reves desde ya muchas gracias, y si tenes algun apuntes de aplicaciones de visual

  5. Gravatar Icon 5 Fernando

    Hasta de utilizar el validate_numericality_of.

  6. Gravatar Icon 6 Jean Carlo Schechnner

    Corrijeme si me equivoco pero en la action enviar_formulario es errores = validar_formulario(params) en lugar de errores = validar_folleto(params)

  7. Gravatar Icon 7 Fernando

    Tienes toda la razón Jean Carlo. Se me fue el nombre en el copy paste :)

    Muchas gracias!

  8. Gravatar Icon 8 Jean Carlo Schechnner

    Fernando, donde puedes cambiar los mensajes de error por defecto porque estan en ingles, y como puedo aaceder a ellos individualmente?

  9. Gravatar Icon 9 Fernando

    Esa era la segunda parte del artículo, que require modificar el plugin para redefinir los mensajes de error. Si estás interesado lo cuento en otro post :)

  10. Gravatar Icon 10 Jean Carlo Schechnner

    ok, lo espero ojala sea pronto ;)

  11. Gravatar Icon 11 miguel michelson

    Hola Fernando , gracias por el post, es muy util.

    Lo unico que me no se como hacer es para que despues de la validacion el formulario mantenga los datos en cada text_input, ya qe cuando se realiza la validacion el formulario aparece con los campos en blanco ¿es posible conseguir esto?

    Gracias

  12. Gravatar Icon 12 miguel michelson

    Hola Fernando , gracias por el post, es muy util.

    Lo unico que me no se como hacer es para que despues de la validacion el formulario mantenga los datos en cada text_input, ya qe cuando se realiza la validacion el formulario aparece con los campos en blanco ¿es posible conseguir esto?

    Gracias

  13. Gravatar Icon 13 CISPISSUERT

    Hi nice site
    Test Link

Deja tu Comentario



Sobre este blog

Blog personal de Fernando Blat, sobre tecnologías web, y programación, ¿o era al revés?

Technorati

Mi del.icio.us