Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CakePHP 3 Validate unique within two columns

I have a table of product sizes

Product Details
id  product_id size
1       1        m
1       1        l
2       2        l

If i try to add another detail to product 1 with size m it should return false but for product 2 size m should go through

In my Product Detail Table here is validator its something here

 //Product Detail Table
public function validationDefault(Validator $validator){
$validator
        ->add('size', 'unique', ['rule' => 'validateUnique', 'provider' => 'table'])

Not sure how to add a condition for column

like image 958
artSir Avatar asked Dec 04 '22 02:12

artSir


1 Answers

That's what the scope option is there for, it allows you to add additional fields to the uniqueness constraint.

Unique validation can be scoped to the value of another column:

$validator->add('email', [
    'unique' => [
        'rule' => ['validateUnique', ['scope' => 'site_id']],
        'provider' => 'table'
    ]
]);

In the above example, the email uniqueness will be scoped to only rows having the same site_id. Scoping will only be used if the scoping field is present in the data to be validated.

API > \Cake\ORM\Table::validateUnique()

However, this should at least additionally be an application rule, as it's prone to race conditions, and thus needs to be checked in a transaction, which by default only happens for application rules.

You can use the built-in IsUnique rule, which you can simply pass multiple column names to.

use Cake\ORM\RulesChecker;

// ...

public function buildRules(RulesChecker $rules)
{
    $rules->add($rules->isUnique(['product_id', 'size']));

    return $rules;
}

See also

  • Cookbook > Database Access & ORM > Validating Data > Applying Application Rules
  • Cookbook > Database Access & ORM > Validating Data > Creating Unique Field Rules
  • Cookbook > Database Access & ORM > Validating Data > Using Validation as Application Rules
like image 87
ndm Avatar answered Dec 19 '22 03:12

ndm