2010-03-17 30 views
7

Tôi có một mẫu đăng ký trong đó người dùng có thể điền vào hai địa chỉ email (email1 & email2). Yêu cầu của tiếp thị là họ cần phải là duy nhất (duy nhất như trong nếu chúng tôi có 10 người dùng, thì sẽ có 10 * 2 = 20 địa chỉ email duy nhất).cakephp isUnique cho 2 trường?

Hệ thống đã được xây dựng trên cakephp, vì vậy điều tôi muốn biết là, có điều gì đó tương tự với tính năng isUnique (duy nhất trong một trường) có thể thực hiện việc này ngay? Hay tôi phải tự mình viết mã này? Cảm ơn trước.

EDIT: xây dựng trên ví dụ của Richard, điều này đã làm việc cho tôi:

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); 
} 
+1

Lưu ý rằng các phiên bản mới hơn của CakePHP2.x hỗ trợ một mảng cho http://book.cakephp.org/2.0/en/models/data-validation.html#Model::Validation::isUnique để cho phép nhiều trường theo mặc định hiện nay. – mark

Trả lời

12

tôi đăng một giải pháp này trên Google Group CakePHP:

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

Thêm dòng sau vào AppModel của bạn:

 /** 
     * 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); 
     } 
} 

và được sử dụng trong mô hình của bạn xác thực:

 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" 
         ) 
       ) 
     ); 
+0

Cảm ơn bạn đã khởi đầu! Tôi đã phải sửa đổi nó một chút để có được nó làm việc cho tình hình của tôi mặc dù. Sẽ chỉnh sửa câu hỏi gốc với mã cuối cùng. – jodeci

+0

'if (isset ($ this-> data [$ this-> name] [$ this-> primaryKey])) { $ tmp [$ this-> primaryKey] =" <> ". $ This-> data [$ this-> name] [$ this- > primaryKey]; 'nên được loại bỏ, vì Bánh 2.x làm cho kiểm tra này bằng chính nó trong phương thức' isUnique'. Tệ hơn nữa, nó làm cho isUnique trả về không chính xác cho tôi. – OlivierH

-2

Theo như tôi nhớ, bạn phải loại này thực thi bằng cách sử dụng phương pháp beforeSave trong mô hình. Tôi đã có một yêu cầu rằng một đối tượng có ít nhất một trong những bộ n N, và tôi chỉ có thể làm theo cách này.

Chỉnh sửa: thử this thread để xem có bất kỳ điều gì giải quyết được sự cố của bạn hay không.

-1

Có và không.

Có, bạn sẽ phải tự viết mã, nhưng trong thành phần xác thực CakePHP.

Thành phần xác thực có cơ chế cho phép quy tắc xác thực tùy chỉnh. Về cơ bản, bạn đặt tên hàm bên trong $ validate (như bình thường). Bạn phải xác định hàm; trong trường hợp này, nó khá đơn giản (chỉ cần thực thi yêu cầu double của bạn làUnique).

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

11

checkUnique chỉ có thể được viết dưới dạng trình bao bọc cho isUnique.

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

và được sử dụng trong mô hình Validate của bạn:

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' 
     ) 
    ) 
); 
+0

Đây là câu trả lời đơn giản hơn nhiều so với câu trả lời ban đầu. –

+1

@KimStacks Chức năng này không khả dụng trong CakePHP khi tôi viết câu trả lời gốc – RichardAtHome

+0

OK. Cảm ơn bạn đã cho tôi biết @RichardAtHome –

-1

Tại nguy cơ bị đánh đập về người đứng đầu và vai để cung cấp một giải pháp phi CakePHP, hãy để tôi trình bày sau đây.

Tạo chỉ mục duy nhất trong cơ sở dữ liệu của bạn qua nhiều cột bạn cần.

chuẩn cú pháp SQL của việc này là:

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

Nơi bạn "$ this-> Model-> save()" lệnh bên trong một "try/catch" khối. Trong khối "catch", kiểm tra ngoại lệ cho mã lỗi. Trong MySQL, một sự vi phạm khóa duy nhất là mã lỗi 23000, nhưng bạn cũng nên chuẩn bị cho các lỗi khác có thể xảy ra.

Thật nhanh chóng và đơn giản và không liên quan đến việc đếm dấu ngoặc đơn.

Bạn nên luôn luôn đặt mã truy cập cơ sở dữ liệu bên trong khối "try/catch". Một phần xử lý ngoại lệ của bạn nên bao gồm ghi nhật ký bất kỳ thông báo lỗi không mong muốn nào. Bạn không thể mong đợi CakePHP làm mọi thứ cho bạn.

+0

Tôi thấy câu trả lời của tôi đã được bỏ phiếu. Không vấn đề. Tôi cho rằng giải pháp của tôi đơn giản hơn, có lẽ nhanh hơn và chắc chắn liên quan đến việc viết mã ít hơn nhiều so với câu trả lời "đúng" được chỉ định. – UncaAlby

2

From cakePHP 2.0 documentation:

Bạn có thể xác nhận rằng một tập hợp các lĩnh vực là duy nhất bằng cách cung cấp nhiều lĩnh vực và đặt $ hoặc false:

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

Hãy chắc chắn để bao gồm các lĩnh vực ban đầu trong danh sách các lĩnh vực khác khi tạo quy tắc duy nhất trên nhiều trường.

Nếu trường được liệt kê không được bao gồm trong dữ liệu mô hình, thì trường đó được coi là giá trị rỗng. Bạn có thể cân nhắc việc đánh dấu các trường được liệt kê theo yêu cầu.

Các vấn đề liên quan