Вопрос

У меня есть регистрационная форма, в которой пользователи могут указать два адреса электронной почты (email1 и email2).Требование маркетинга заключается в том, что они должны быть уникальными (уникальными, например, если бы у нас было 10 пользователей, то было бы 10*2=20 уникальных адресов электронной почты).

Система уже построена на cakephp, поэтому мне хотелось бы знать, есть ли что-то похожее на функцию isUnique (уникальная в одном поле), которая может сделать это прямо из коробки?Или я обречен писать это сам?Заранее спасибо.

РЕДАКТИРОВАТЬ:построенный на примере Ричарда, у меня это сработало:

function checkUnique($data, $fields) {
    if (!is_array($fields)) {
        $fields = array($fields);
    }
    foreach($data as $key) {
        $checks = $key;
    }
    if (empty($checks)) {
      return true;  //allow null
    }
    foreach($fields as $key) {
        $tmp[$key] = $checks;
    }
    if (isset($this->data[$this->name][$this->primaryKey])) {
        $tmp[$this->primaryKey] = "<>".$this->data[$this->name][$this->primaryKey];
    }
    return $this->isUnique($tmp);
}
Это было полезно?

Решение

Я опубликовал решение этой проблемы в группе Google CakePHP:

http://groups.google.com/group/cake-php/browse_frm/thread/b3a1e4ae3eeb6091/e168f54bac27c163?lnk=gst&q=checkUnique#e168f54bac27c163

Добавьте в свою AppModel следующее:

        /** 
         * checks is the field value is unqiue in the table 
         * note: we are overriding the default cakephp isUnique test as the 
original appears to be broken 
         * 
         * @param string $data Unused ($this->data is used instead) 
         * @param mnixed $fields field name (or array of field names) to 
validate 
         * @return boolean true if combination of fields is unique 
         */ 
        function checkUnique($data, $fields) { 
                if (!is_array($fields)) { 
                        $fields = array($fields); 
                } 
                foreach($fields as $key) { 
                        $tmp[$key] = $this->data[$this->name][$key]; 
                } 
                if (isset($this->data[$this->name][$this->primaryKey])) { 
                        $tmp[$this->primaryKey] = "<>".$this->data[$this->name][$this- 
>primaryKey]; 

                } 
                return $this->isUnique($tmp, false); 
        } 
} 

и используется в проверке вашей модели:

        var $validate = array( 
                "name"=>array( 
                        "unique"=>array( 
                                "rule"=>array("checkUnique", array("name", "institution_id")), 
                                "message"=>"A contact with that name already exists for that 
institution" 
                        ) 
                ) 
       ); 

Другие советы

checkUnique можно просто написать как обертку для isUnique.

class AppModel extends Model {
    public function checkUnique($ignoredData, $fields, $or = true) {
        return $this->isUnique($fields, $or);
    }
}

и используется в проверке вашей модели:

public $validate = array(
    'name' => array(
        'unique' => array(
            'rule' => array('checkUnique', array('name', 'institution_id'), false), 
            'message' => 'A contact with that name already exists for that 
institution'
        )
    )
);

Из документации cakePHP 2.0:

Вы можете проверить уникальность набора полей, указав несколько полей и установив для $or значение false:

public $validate = array(
    'email' => array(
        'rule' => array('isUnique', array('email', 'username'), false),
        'message' => 'This username & email combination has already been used.'
    )
);

Обязательно включите исходное поле в список полей при создании уникального правила для нескольких полей.

Если указанное поле не включено в данные модели, оно рассматривается как нулевое значение.Вы можете рассмотреть возможность пометки перечисленных полей как обязательные.

Да и нет.

Да, вам придется написать код самостоятельно, но в рамках компонента проверки CakePHP.

Компонент проверки имеет механизм, позволяющий настраивать правила проверки.По сути, вы помещаете имя функции в $validate (как обычно).Вам нужно определить функцию;в данном случае это довольно просто (просто выполните требование double isUnique).

http://book.cakephp.org/2.0/en/models/data-validation.html#custom-validation-rules

Рискуя получить удары по голове и плечам за предложение не-CakePHP Решение, позвольте мне представить следующее.

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

Стандартный синтаксис SQL для этого:

create unique index {IndexName} on {Table} ({Column}, {Column}, ...)

Поместите команду «$this->Model->save()» внутри блока «try/catch».В блоке «catch» проверьте исключение для кода ошибки.В MySQL уникальным нарушением ключа является код ошибки 23000, но вы должны быть готовы и к другим возможным ошибкам.

Это быстро и просто и не требует подсчета круглых скобок массива.

Вам следует всегда В любом случае поместите код доступа к базе данных внутри блока «try/catch».Часть обработки исключений должна включать регистрацию любых неожиданных сообщений об ошибках.Вы не можете ожидать, что CakePHP сделает все для тебя.

Насколько я помню, для такого рода принудительного применения приходится использовать beforeSave метод в модели.У меня было требование, чтобы у объекта был установлен хотя бы один из N fks, и я мог сделать это только таким образом.

Редактировать:пытаться эта тема чтобы посмотреть, решит ли что-нибудь вашу проблему.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top