I need help with creating a validation rule for the following scenario:
sites
+id
+name
containers
+id
+site_id
+name
Table “containers” has a uniqueness constraint on (site_id, name) to ensure that there is, for example, only one container named “beets” at any site with the same name. This works as expected. In the MySQL client, when I try to create a second container named beets at a site, I get the expected constraint violation error.
This works in CakePHP too, but I get an ugly error message. I looked in the ContainersTable.php class, and there here is what I see for the validation code:
<?php
namespace App\Model\Table;
use App\Model\Entity\Container;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
/**
* Containers Model
*
* @property \Cake\ORM\Association\BelongsTo $Sites
* @property \Cake\ORM\Association\BelongsToMany $Groups
*/
class ContainersTable extends Table
{
/**
* Initialize method
*
* @param array $config The configuration for the Table.
* @return void
*/
public function initialize(array $config)
{
parent::initialize($config);
$this->table('containers');
$this->displayField('name');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->belongsTo('Sites', [
'foreignKey' => 'site_id'
]);
$this->belongsToMany('Groups', [
'foreignKey' => 'container_id',
'targetForeignKey' => 'group_id',
'joinTable' => 'containers_groups'
]);
}
/**
* Default validation rules.
*
* @param \Cake\Validation\Validator $validator Validator instance.
* @return \Cake\Validation\Validator
*/
public function validationDefault(Validator $validator)
{
$validator
->uuid('id')
->allowEmpty('id', 'create');
$validator
->requirePresence('site_id')
->notEmpty('site_id')
->uuid('id');
$validator
->requirePresence('name')
->notEmpty('name');
return $validator;
}
/**
* Returns a rules checker object that will be used for validating
* application integrity.
*
* @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
* @return \Cake\ORM\RulesChecker
*/
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->existsIn(['site_id'], 'Sites'));
return $rules;
}
}
Any ideas on how to write the code to ensure that we don’t have multiple “beets” container objects at “Grocery Store” site?
@Graziel, any ideas on this?