I have a working belongsToMany association between my Proyectos and my Medios models. If I add a new Proyecto entity, I can select from among the registered Medios, and everything is adequately saved. The thing is the entity is correctly saved whether I select any Medio or not, and I want it to be a required field in the form.
I tried adding a "required => true" at the form, and a "$validator->notEmpty" at the ProyectoTable, but it doesn't work. (It still saves the form even if no Medio is selected.)
I have been reading the CakePHP 3.x documentation, but for the life of me I haven't found the correct way to validate the associated data's presence. What am I missing? (I suppose I should add some kind of special rule, but I don't get how and where should I put it.)
My Model:
class ProyectosTable extends Table
{
public function initialize(array $config)
{
parent::initialize($config);
[...]
$this->belongsToMany('Medios', [
'foreignKey' => 'proyecto_id',
'targetForeignKey' => 'medio_id',
'joinTable' => 'medios_proyectos',
]);
}
public function validationDefault(Validator $validator)
{
[...]
$validator
->requirePresence('medios', 'create')
->notEmpty('medios');
return $validator;
}
}
My Controller:
public function add()
{
$proyecto = $this->Proyectos->newEntity();
if ($this->request->is('post')) {
$partida = $this->Proyectos->patchEntity($proyecto, $this->request->getData());
if ($this->Proyectos->save($proyecto)) {
$this->Flash->success('El proyecto ha sido salvado.');
return $this->redirect(['action' => 'index']);
}
$this->Flash->error('El proyecto no pudo ser salvado.');
}
$medios = $this->Proyectos->Medios->find('list', ['limit' => 200]);
$this->set(compact('proyecto','medios'));
}
My View:
<?= $this->Form->create($proyecto) ?>
[...]
<?= $this->Form->control('medios._ids', ['options' => $medios,'required' => true]); ?>
[...]
<?= $this->Form->button('submit') ?>
<?= $this->Form->end() ?>
I already tried changing it to "$validator->requirePresence('medios._ids', 'create')->notEmpty('medios._ids');" in the model, but then the view throws me the "can't save, required field" error, whether I select one, all or no Medio at all.
Multi select controls do have a hidden fallback like this:
So when nothing is selected, the field is still present, indicating an empty selection. Using
._ids
you are creating a nested structure, so the value that is being submitted formedios
will never be interpreted as empty, you'd receive something like this:So the
notEmpty
rule of course won't apply here. Also validation rule field names do not support the dot syntax, they strictly map to first level fields.What you can do is for example using a nested validator for the
medios
field, the rules of that validator would apply to the fields nested undermedios
. Something along the lines of this:See also