MVC Pregunta: ¿Debo poner reglas de validación de formularios en el controlador o modelo?


Por un lado, la validación de formularios podría verse como parte de la lógica de la aplicación y, por lo tanto, pertenecer al modelo.

Por otro lado, se ocupa directamente de la entrada que viene de la vista y maneja los errores de visualización, etc. Desde ese ángulo tiene más sentido ponerlo en controladores.

¿Cuál es el enfoque correcto desde el punto de vista de MVC?

P. S mi validación de formulario en realidad consiste solo en escribir una lista de campos, sus reglas, y pasarla a un biblioteca de validación de formularios, que devuelve true / false si pasó la validación o no.

Ejemplo:

$this->load->library('form_validation');
$this->form_validation->set_rules('name', 'Name', 'required');
$this->form_validation->set_rules('email', 'Email', 'required|valid_email');
//........
if ($this->form_validation->validate())
    // Process data
else
    $this->register_form(); //A controller action that will show a view with errors

¿Se debe poner esto en un controlador o modelo?

Author: tereško, 2011-04-13

9 answers

La validación es el problema del modelo. Solo model sabe cómo deberían verse sus datos. Usted describe sus campos de datos en el modelo, por lo que debe describir las reglas de validación para estos campos en el mismo lugar.

Parece obvio para mí, pero con mucho gusto escucharía a los oponentes.

 19
Author: Nemoden,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-13 15:06:38

Idealmente, desea 3 capas de validación:

  1. Vista: Lado del cliente (javascript, validación html5, etc.). Esto detecta errores y omisiones obvios antes de que los datos lleguen al controlador, perdiendo el tiempo del usuario e invocando una carga de página innecesaria si hay errores.
  2. Controlador: Esta es su capa de validación Formulario. Los controladores generalmente están destinados a manejar la entrada directamente y enviarla al modelo. Es muy raro que cada campo en su formulario tiene una columna directamente relacionada en su base de datos, generalmente necesita alterar los datos de alguna manera antes de pasarlos al modelo. Solo porque tenga un campo que necesita validar llamado "confirmar correo electrónico", no significa que su modelo tratará con un valor de" confirmar correo electrónico". A veces, este será el paso final de validación.
  3. Model : Esta es su última línea de defensa para la validación, y posiblemente su única validación en el caso de enviar datos al modelo sin que viene directamente de un mensaje de formulario. Hay muchas veces en las que necesita enviar datos a la base de datos desde una llamada del controlador, o con datos que no son de entrada del usuario. No queremos ver errores de BD, queremos ver errores lanzados por la propia aplicación. Por lo general, los modelos no deben tratar directamente con los datos $_POST o la entrada del usuario, sino que deben recibir datos del controlador. Usted no quiere estar tratando con datos inútiles aquí como la confirmación de correo electrónico.
 71
Author: Wesley Murch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-13 22:13:18

Yo diría que el código de validación del formulario debe estar en el controlador (no en el modelo) en la mayoría de los casos.

Madmartigan lo puso mejor en su comentario de arriba " Form validation != = Validación de datos. No todas las formas interactúan con un modelo "

Los formularios web son lógicamente parte de la parte de Vista/Controlador de MVC, ya que el usuario interactúa con ellos en la vista.

 12
Author: JohnWright,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-13 19:57:12

Parece que todo el mundo siempre dice modelo de manos a esta pregunta, que tiene sus méritos (en comparación con lo contrario), pero creo que la respuesta a la pregunta es más sutil. La validación de los propios datos debe realizarse en el modelo.

Pero hay otros tipos de validación, como si el formulario ha sido enviado con campos inesperados (por motivos de seguridad, obviamente) o si un usuario tiene permiso para realizar la operación solicitada. Por al poner estos tipos de validación en el modelo, cimenta el modelo (una abstracción de los datos) para separar completamente cosas, como cómo funciona el sistema de usuario o cómo se evalúan los envíos de formularios con fines de seguridad.

Puedes imaginar cambiar una de esas clases o sistemas de clases, y luego tener un lío porque también tienes que cambiar todos tus modelos. Mientras que los controladores son el mediador entre la entrada del cliente y los datos: en ese papel, son los validadores adecuados de los ejemplos anteriores, y probablemente muchos otros.

 5
Author: Ryan Williams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-28 00:59:35

Teniendo en cuenta otras respuestas (y algunas investigaciones), si tiene que validar datos con reglas como campos no vacíos, validación de correo electrónico y cosas, el Controlador no debe permitir que estos datos pasen por sí mismo, pero si tiene reglas como "solo un usuario con una reputación mayor que 150 puede rechazar una respuesta", debe hacer esto en la capa del modelo.

Si desea tener validación de reglas de negocio, le aconsejo que tenga un objeto como el Patrón de Objeto de negocio, con eso, en cualquier parte del software cuando desea "rechazar una respuesta", tiene su lógica de negocio conservada y centralizada.

 2
Author: ViniciusPires,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-21 17:00:28

Es una discusión teórica interesante, pero si nos centramos en el punto de que la pregunta se hizo en el contexto de Codeigniter(CI):

En CI puede especificar una regla de validación personalizada como esta:

$this->form_validation->set_rules('email', 'Email', 'required|callback_my_validation');

En este escenario, debe definir una función pública llamada "my_validation" que debe devolver true o false y el framework agregará el error (si se devuelve false) a una pila de errores.

So... si pones este código en el controlador, son inadvertidamente exponiendo una url pública , lo que significa que sería posible llamar a algo como " http://yoursite.com/my_validation " (No creo que pretendas eso). La única manera de proteger esta url sería ir a las " rutas.php " y evitar allí el acceso a esta url. Esto no parece práctico y parece indicarnos en la dirección en que los desarrolladores de CI pretendían que manejáramos la validación en el modelo.

 2
Author: Luís Osório,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-24 02:41:58

El modelo debe validar sus propios datos.

Digamos que tiene un modelo de contacto, que solo requiere un nombre y un número de teléfono. Debe validar que el nombre y el número de teléfono están llenos.

Sin embargo, si este modelo de contacto es parte de una Cotización, es posible que también necesite un nombre completo y una dirección de correo electrónico.

En ese caso, puede extender el modelo Contact (para ser un modelo QuoteContact) y agregar más validaciones, o puede hacer las validaciones adicionales en el modelo Quote.

Debe escribir sus modelos para que sean reutilizables en otras aplicaciones (incluso si nunca lo serán), por lo que deben ser independientes del controlador. Si las validaciones están en el controlador, entonces perderá esas validaciones si cambia a decir una versión de línea de comandos.

 1
Author: Neil McGuigan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-29 19:39:17

Si valida el formulario en serverside usando codeigniter entonces se valida en controller

Necesitas incluir la librería form_validation usando autoload como esta

$autoload['libraries'] = array("form_validation") 

O directamente se carga en el controlador

$this->load->library('form_validation');

Luego se establece la regla de validación para cada campo del formulario

$this->form_validation->set_rules('username', 'User Name', 'required');
$this->form_validation->set_rules('useremail', 'User Email', 'required|valid_email');

Si se encuentra algún error después de la validación, un campo de formulario se captura en la función validar

if ($this->form_validation->validate()) {
    //return back to form
} else {
    //successful validate all field 
}
 0
Author: prash.patil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-29 09:56:00

Hay otro ángulo a esto no cubierto en las otras respuestas. Depende de lo que usted está diciendo que Controlador / Vista es! Si es Javascript el que comprueba la validación a medida que los usuarios escriben, por razones de seguridad también debería tener una validación en su backend (esto podría estar nuevamente en el controlador de su backend o modelo porque cualquiera puede simplemente enviar Datos a través de Ajax sin el navegador.

Para razones de rendimiento, usted debe tener un validación en tu front end controller / view también porque no quieres estar golpeando tu base de datos cada vez que un usuario selecciona una Fecha de nacimiento no válida o algo así.

Así que aparte de la base teórica de validación en M, V, y / o C también debe considerar la practicidad de frontend vs backend independientemente de MVC.

Mi recomendación personal es no limitarse a un solo nivel de validación. Una validación mal colocada (como la Contraseña de Confirmación ejemplo mencionado en las otras respuestas) puede tener serias implicaciones en la arquitectura.

 0
Author: Gaurav Ramanan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-12 06:08:29