Home PageКаталог Изменения НовыеКомментарии Пользователи Регистрация
CakePHP: Code/Models/UniqueFieldsValidation ...

Расширение модели для валидации уникальных полей


Автор: Макаров Александр


20-го декабря нашёл в коде досадный недочёт: проверка на уникальность срабатывала при редактировании записи. Исправил.


Меня очень напрягало в Cake 1.1 то, что не было никаких средств проверки поля модели на уникальность. В Cake 1.2 добавили isUnique, но вот только забыли про то, что хорошо бы было добавить ещё один магический массив вроде $validate в модели.


Я решил исправить этот недостаток:


<?php  
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.


Теперь в наших моделях можно проделать вот такую-вот штуку:


<?php
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('Сохранить');?>


Также можно производить проверку на уникальность по нескольким полям или по группе полей:

<?php
var $unique = array('title''text');
//или
var $unique = array('title', array('firstname''lastname'));
?>


Соответственно в View код для второго случая будет выглядеть так:


<?=$form->error('Post/unique_firstname_lastname''Уже есть такой автор!');?>


 
Комментарии

Спасибо за полезность! Но я так и не понял код для 1.1 или 1.2 (с 1.2 не работал).

vgn-home.telenet.ru (2008-01-12 23:11:52)

судя по используемому хелперу форм 1.2
Спасибо автору, действительно полезный код, к тому-же его можно использовать и при построении списков уникальных значений таблицы в случаях когда значения могут повторятся.

4seek.org (2008-04-26 03:37:09)
Эта функция проверяет поля с учетом регистра? Если да, то как сделать чтобы проверяла без учета?
Заранее благодарен за помощь.
92.127.126-92.xdsl.ab.ru (2009-10-04 18:24:10)
Добавить комментарий:

Файлов нет. [Показать файлы/форму]