4

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

ndm
  • 59,784
  • 9
  • 71
  • 110
artSir
  • 540
  • 1
  • 8
  • 29

1 Answers1

16

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

ndm
  • 59,784
  • 9
  • 71
  • 110
  • Thank you, i knew it existed but couldn't find it. Also your first example didn't work for me but the second one did. Do you have an idea why. – artSir Aug 24 '15 at 15:25
  • @artSir I can't tell without at least seeing the involved code, ie the validation rules and the code that triggers the validation. Note that the first example is just a quote from the docs. – ndm Aug 24 '15 at 15:46
  • Sorry i should of framed my question better, what is the difference between the validator and the buildrules. Like which gets called first? Build rules are only on create right? And validator is on all create and update correct? – artSir Aug 24 '15 at 17:42
  • 1
    @artSir No, they are invoked in two different places, see **http://book.cakephp.org/3.0/en/orm/validation.html#validation-vs-application-rules** – ndm Aug 24 '15 at 17:56
  • thank you, it makes sense now, i thought validator got called on save() but it doesn't only newEntity and patchEntity. – artSir Aug 24 '15 at 19:21