tutorial plantillas para blocks aprender cakephp

plantillas - layout default cakephp



ValidaciĆ³n de formulario HABTM en CakePHP (7)

El blog de teknoid tiene una solución bastante profunda para su problema aquí. La forma más fácil de hacer esto de Cakey sería agregar una validación personalizada a su modelo, como menciona en su comentario anterior. Consulte http://teknoid.wordpress.com/2008/10/16/how-to-validate-habtm-data/

Del artículo, donde Tag HABTM Post (:: Project HABTM Users):

Primero, validamos el modelo de etiqueta, utilizando los datos del formulario para garantizar que se haya seleccionado al menos una etiqueta. Si es así, guardamos la publicación y las etiquetas relevantes.

Tengo una tabla de proyectos y una tabla de usuarios que están vinculados por una relación HABTM. En la página "agregar" nuevo proyecto, tengo una sección de casilla de verificación múltiple para seleccionar Usuarios para el nuevo proyecto. Quiero tener al menos un Usuario para el Proyecto. ¿Cuál es la mejor manera de abordar esto en CakePHP?


Prueba esto:

// app/models/project.php /** * An additional validation check to ensure at least one User is * selected. Spoofs Cake into thinking that there are validation * errors on the Project model by invalidating a non-existent field * on the Project model, then also invalidates the habtm field as * well, so when the form is re-displayed, the error is displayed * on the User field. **/ function beforeValidate() { if (!isset($this->data[''User''][''User'']) || empty($this->data[''User''][''User''])) { $this->invalidate(''non_existent_field''); // fake validation error on Project $this->User->invalidate(''User'', ''Please select at least one user''); } return true; }


Acabo de ver su problema yo mismo en un proyecto y encontré una solución un poco más elegante, siempre y cuando solo se trate de una relación habtm y deba asegurarse de que se haya seleccionado al menos una casilla de verificación.

entonces, por ejemplo, estás editando un Proyecto y quieres que esté asociado con al menos un usuario

Agregar esto a beforeValidate ()

// verifica el modelo habtm y agrega datos

foreach($this->hasAndBelongsToMany as $k=>$v) { if(isset($this->data[$k][$k])) { $this->data[$this->alias][$k] = $this->data[$k][$k]; } }

En las reglas de validación, agregue lo siguiente:

''User'' => array( ''rule'' => array(''multiple'', array(''min'' => 1)), ''message'' => ''Please select one or more users'' )


Si está utilizando CakePHP 2.3.x , puede que necesite agregar este código a su modelo además del código que GuidoH proporcionó, de lo contrario, los datos de su modelo HABTM podrían no guardarse:

public function beforeSave($options = array()){ foreach (array_keys($this->hasAndBelongsToMany) as $model){ if(isset($this->data[$this->name][$model])){ $this->data[$model][$model] = $this->data[$this->name][$model]; unset($this->data[$this->name][$model]); } } return true; }


Me encontré con el mismo problema, pero ahora, 3 años después, con CakePHP 2.3 .

Para ser claro; Group tiene y pertenece al User . He tenido un formulario como este:

// View/Groups/add.ctp echo $this->Form->input(''name''); echo $this->Form->input(''User'');

Con la regla de validación como en la respuesta del usuario448164:

// Model/Group.php public $validate = array( ''User'' => array( ''rule'' => array(''multiple'', array(''min'' => 1)), ''message'' => ''Please select one or more users'' ) );

Eso no funcionó, después de buscar en Google, encontré esta pregunta que no podría ser la mejor solución. Luego probé varias cosas y descubrí que funcionaba bien:

// View/Groups/add.ctp echo $this->Form->input(''name''); echo $this->Form->input(''Group.User'');

Una solución demasiado fácil, pero tuvo que profundizar para descubrir que funciona de esta manera.

Espero que ayude a alguien algún día.

Actualización para CakePHP 2.4.x (posiblemente 2.3.x también)

Cuando escribí esta respuesta, estaba usando CakePHP 2.3.x. En aquel entonces, funcionó perfectamente tanto para validar como para guardar los datos. Ahora, al aplicar el mismo código en un nuevo proyecto, usando CakePHP 2.4.x, ya no funcionaba.

Creé un caso de prueba, usando el siguiente código:

$data = array( ''User'' => array( ''Client'' => array(8) ), ); $this->User->create(); $this->User->saveAll($data);

Mi primer pensamiento fue: Guardar todo significa guardar todos los modelos "raíz", lo que realmente tiene sentido para mí. Para ahorrar más profundo que solo los "raíz", tendrá que agregar la opción deep . Así que terminé con el siguiente código:

$data = array( ''User'' => array( ''Client'' => array(8) ), ); $this->User->create(); $this->User->saveAll($data, array(''deep'' => true));

¡Funciona de maravilla! Feliz codificación. :)

Actualización (2014/03/06)

Luchando con el mismo problema nuevamente, en este caso con hasMany lugar de habtm . Parece que se comporta de la misma manera. Pero me encontré buscando esta respuesta nuevamente, y me confundí.

Me gustaría dejar en claro que es clave usar Group.User lugar de User en su entrada. De lo contrario, no usará la validación del modelo de User .


Según mi comentario en la respuesta anterior de Guido, uso la respuesta de Guido exactamente, sin embargo modifico los datos con la devolución de llamada beforeSave antes de que se guarde en la base de datos.

Tengo este problema en Cake 2.4.5+

public function beforeSave($options = array()) { $temp = $this->data[''Group''][''User'']; unset($this->data[''Group''][''User'']); $this->data[''User''][''User''] = $temp; return true; }


Actualización de 2016 para CakePhp 2.7

Respuesta completa aquí: validación de formulario HABTM con CakePHP 2.x

TL; DR;

AppModel.php

public function beforeValidate($options = array()){ foreach (array_keys($this->hasAndBelongsToMany) as $model){ if(isset($this->data[$model][$model])) $this->data[$this->name][$model] = $this->data[$model][$model]; } return true; } public function afterValidate($options = array()){ foreach (array_keys($this->hasAndBelongsToMany) as $model){ unset($this->data[$this->name][$model]); if(isset($this->validationErrors[$model])) $this->$model->validationErrors[$model] = $this->validationErrors[$model]; } return true; }

En el modelo principal de tu HABTM:

public $validate = array( ''Tag'' => array( ''rule'' => array(''multiple'', array(''min'' => 1)), ''required'' => true, ''message'' => ''Please select at least one Tag for this Post.'' ) );