I have a couple of columns (ip, provider_id) for which I want combinations of values to always be unique. Therefore, I am trying to build a custom validation function. But I am having issues grabbing on the value of the secondary field. This is my code so far in the model:
public $validate = array(
'ip' => array(
'rule' => array('uniqueClick', 'provider_id'),
'message' => 'The click is not unique.'
)
);
public function uniqueClick ($ip, $field) {
$count = $this->find('count', array('conditions' => array('ip' => $ip, 'provider_id' => $field)));
// echo $field;
return $count == 0;
}
So the problem is that when I am testing what value is loaded into $field, it's just 'provider_id', a string. I was hoping it would contain the value of the 'provider_id' field. Does anyone know how to grab that value (and all other secondary model field values if necessary) and send it to the custom validation function?
My reading in the CookBook and people who've discussed similar problems seemed to suggest this solution would work, but not for me unfortunately.
Thanks in advance!
Cake is definitely behaving the way it's supposed to there. The second paramameter that you pass in that 'rule' array is meant to be passed as a static value.
However, your provider_id should be available in $this->data['MyModel']['provider_id']
So you should be able to forget about that second parameter completely, and do:
public function uniqueClick ($ip) {
$count = $this->find('count', array(
'conditions' => array(
'ip' => $ip,
'provider_id' => $this->data[$this->alias]['provider_id'])
));
return $count == 0;
}
Hope that helps!
To complement Joshua's answer, the validation array should be build like this:
// Validation rules
public $validate = array(
'ip' => array(
'rule' => array('uniqueClick', 'ip'),
'message' => 'The click is not unique.'
)
);
/**
* Checks if there are records on the datasource with the same ip and same provider_id
*
*/
public function uniqueClick ($ip) {
$count = $this->find('count', array(
'conditions' => array(
'ip' => $ip,
'provider_id' => $this->data[$this->alias]['provider_id'])
));
return $count == 0;
}
you can also use my rule with is able to work with as many fields as you need
try http://www.dereuromark.de/2011/10/07/maximum-power-for-your-validation-rules/ and https://github.com/dereuromark/tools/blob/master/Model/MyModel.php#L930
so basically the same than you tried:
'ip' => array(
'validateUnique' => array(
'rule' => array('validateUnique', array('provider_id')),
'message' => 'You already have an entry',
),
),
You can directly go with this solution without passing anything in validation rules except the custom unique function.
// Validation rules
public $validate = array(
'ip' => array(
'rule' => array('uniqueClick'),
'message' => 'The click is not unique.'
)
);
/**
* Checks if there are records on the datasource with the same ip and same provider_id
*
*/
public function uniqueClick ($ip) {
$count = $this->find('count', array(
'conditions' => array(
'ip' => $ip,
'provider_id' => $this->data[$this->alias]['provider_id'])
));
return $count == 0;
}
$this->data[$this->alias]['provider_id'] automatically gets the value of the provider_id.
来源:https://stackoverflow.com/questions/11173835/cakephp-2-1-custom-validation-rule-check-for-unique-field-value-combination