Reputation: 384
I'm trying to use the validCount validator rule of cakephp 3.x
I have an event, with a maximum number of participants (Event->max_pax)
I would like to add a validation rule that refuses a participant when he is the number max_pax+1.
I'm doing something wrong, but I don't understand what (my code follows)
//This is in Participant Model.php
public function buildRules(RulesChecker $rules)
{
$rules->add(
function ($entity, $options) use ($rules) {
$query = $this->Events->find();
$max_pax = $query->select('max_pax')
->where(['id'=>$entity->event_id])
->first();
$r = $rules->validCount('events', $max_pax , '<=', "maximum $max_pax participants");
debug($r);
return $r;
},
'maxPax',
[
'errorField' => 'event_id',
'message' => "Choose another event"
]
);
Can somebody help?
Upvotes: 0
Views: 163
Reputation: 60463
First of all, if you where to nest rules like that, then you'd have to evaluate them. In your example $r
would be a callable object of type \Cake\Datasource\RuleInvoker
, so you'd do something like:
$result = $r($entity, $options);
And then either further evaluate the validation result (it's a boolean), or return it from your custom rule. Also in your example $max_pax
would be an entity, you'd have to actually access the field on it and pass that to the validCount()
method.
However, validCount()
is ment to be used for counting associated data that currently exists on the given entity, it doesn't do any database lookups, ie it is ment for situations where you save a record including associated records, and want to define restrictions for the number of associated records that can/must be saved. So you could for example use it if you where to create a new event including participants, to ensure that you're not trying to insert more participants than allowed.
When creating records via your participants model, you want to actually query the database in order to count how many participants are already associated to the selected event. There's no built-in rule that does that, so you have to do that on your own, for example something along the lines of this:
$event = $this->Events
->find()
->select(\Cake\ORM\Query $query) {
return [
'Events.max_pax',
'number_of_participants' => $query->func()->count('Participants.id')
];
})
->leftJoinWith('Participants')
->where(['Events.id' => $entity->event_id])
->first();
return $event->get('number_of_participants') < $event->max_pax;
That would query the maximum number of participants allowed and the number of participants that already exist, and then simply compare those values.
Upvotes: 1