/**
* @param array $data
* @param array $options
* - scope (array of other fields as scope - isUnique dependent on
other fields of the table)
* - batch (defaults to true, remembers previous values in order to
validate batch imports)
* example in model: 'rule' => array ('validateUniqueExt',
array('scope'=>array('belongs_to_table_id', 'user_id'))),
* //TODO: test!!!
* 2011-03-27 ms
*/
function validateUniqueExt($data, $options = array()) {
foreach ($data as $key => $value) {
$fieldName = $key;
$fieldValue = $value;
}
$defaults = array('batch'=>true, 'scope'=>array());
$options = array_merge($defaults, $options);
# for batch
if ($options['batch'] !== false && !empty($this->batchRecords)) {
if (array_key_exists($value, $this->batchRecords[$fieldName])) {
return $options['scope'] === $this->batchRecords[$fieldName]
[$value];
}
}
# continue with validation
if (!$this->validateUnique($data, $options['scope'])) {
return false;
}
# for batch
if ($options['batch'] !== false) {
if (!isset($this->batchRecords)) {
$this->batchRecords = array();
}
$this->batchRecords[$fieldName][$value] = $scope;
}
return true;
}
this way it doesnt matter if its called from saveAll() or multiple
validates()
On 27 Mrz., 01:47, cricket <zijn.digi...@gmail.com> wrote:
> On Sat, Mar 26, 2011 at 7:40 PM, euromark <dereurom...@googlemail.com> wrote:
> > I encountered this problem several times with some batch imports or
> > multiple form boxes saved together.
>
> > You have a validation rule "isUnique" for the title.
> > If you validate all your - lets say 15 - records, they are OK, even if
> > two of them have the same name.
> > Thats because the validation can only compare the 15 records to the
> > current db content, not to each other.
>
> > In some cases you could probably just compare the new values and find
> > out if there are more than 2 of the same title.
> > But with some beforeValidation or beforeSave or even behaviors this is
> > not as easy anymore.
>
> > Did anyone find a solution to this problem?
> > I was thinking:
> > Creating "virtual records" in a special "isUnique" validation rule and
> > not only checking on "isUnique" in the DB but also comparing the value
> > to all the previously checked ones.
>
> > If you don't do it this way, some of your records will just be omitted
> > because the validation fails for them, although saveAll() with
> > validate=>first returned true in the first place...
>
> Yes, beforeSave() wouldn't help because it's called for each individual record.
>
> How about something like this in AppModel?
>
> function saveAll($data = null, $options = array())
> {
> if (isset($options) && is_array($options) &&
> isset($options['validate']) && $options['validate'] !== false)
> {
> foreach($this->validate as $key => $rule_set)
> {
> if (isset($rule_set['rule']) && 'isUnique' == $rule_set['rule'])
> {
> $records = Set::extract(
> $this->alias.'/'.$key,
> $data
> );
>
> if (sizeof($records) > array_unique($records))
> {
> $this->validationErrors[$key] = 'non-unique values';
> }
> }
> }
>
> if (sizeof($this->validationErrors))
> {
> return false;
> }
> }
> return parent::saveAll($data, $options);
>
> }
>
> Completely untested. And I'm sure it could use some tightening up.
--
Our newest site for the community: CakePHP Video Tutorials http://tv.cakephp.org
Check out the new CakePHP Questions site http://ask.cakephp.org and help others with their CakePHP related questions.
To unsubscribe from this group, send email to
cake-php+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/cake-php
No comments:
Post a Comment