Cake PHP: Расширение модели для валидации уникальных полей
17 декабря 2007
Меня очень напрягало в Cake 1.1 то, что не было никаких средств проверки поля модели на уникальность. В Cake 1.2 добавили isUnique, но вот только забыли про то, что хорошо бы было добавить ещё один магический массив вроде $validate в модели.
Я решил исправить этот недостаток:
class AppModel extends Model { /** * Use the following syntax to define some unique constraints: * * $unique = array( * 'field1', * array('field2', 'field3') * ); * * @var array */ var $unique = array(); /** * Checks unique constraints. * * @param array $params Array consisting of "field" => "value" * @param int $id PK of record being editited (optional) * @return boolean Validation passed? */ private function checkUnique(array $rules, $id=''){ $isValid = true; // Set Recursive Seach mode. $this->recursive = -1; foreach ($rules as $rule){ // @var array $query Array to $this->hasAny() against $query = array(); if(!is_array($rule)){ $query[$this->name . '.' . $rule] = $this->data[$this->name][$rule]; } else{ foreach($rule as $field){ $query[$this->name . '.' . $field] = $this->data[$this->name][$field]; } } // Check to see if we need to query against an id if (empty($id)){ $query[$this->name.'.id'] = "!= NULL"; } else{ $query[$this->name.'.id'] = "!= {$id}"; } // Run the query. if ($this->hasAny($query)) { if(!is_array($rule)){ $this->invalidate('unique_'.$rule); $isValid = false; } else{ $this->invalidate('unique_'.implode('_', $rule)); $isValid = false; } } } return $isValid; } function beforeValidate(){ // Unique Constraints Check return $this->checkUnique($this->unique, $this->id); } }
Код кладётся в app_model.php в папку app.
Теперь в наших моделях можно проделать вот такую-вот штуку:
class Post extends AppModel { var $name = 'Post'; var $validate = array( 'title' => VALID_NOT_EMPTY, 'text' => VALID_NOT_EMPTY ); var $unique = array('title'); }
И в View сделать так:
<h1>Добавить новость</h1> <?=$form->create('Post'); <?=$form->hidden('Post/id'); <?=$form->input('Post/title', array('size' => '40', 'label' => 'Заголовок: ')) <?=$form->error('Post/unique_title', 'Уже есть новость с таким заголовком!'); <?=$form->textarea('Post/text', array('rows'=>'10', 'label' => 'Текст: ')) <?=$form->end('Сохранить');
Также можно производить проверку на уникальность по нескольким полям или по группе полей:
var $unique = array('title', 'text'); //или var $unique = array('title', array('firstname', 'lastname'));
Соответственно в View код для второго случая будет выглядеть так:
$form->error('Post/unique_firstname_lastname', 'Уже есть такой автор!');
Комментарии RSS по email OK