cakephp 对于 2 个字段来说是唯一的吗?

发布于 2024-08-25 10:02:36 字数 781 浏览 9 评论 0原文

我有一个注册表,用户可以在其中填写两个电子邮件地址(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);
}

I have a registration form in which users can fill in two email address (email1 & email2). Marketing's requirement is that they need to be unique (unique as in if we had 10 users, then there would be 10*2=20 unique email address).

The system is already built on cakephp, so what I'd like to know is, is there something similar to the isUnique feature (unique in one field) that can do this right out of the box? Or am I doomed to code this myself? Thanks in advance.

EDIT: built on Richard's example, this worked for me:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

紫轩蝶泪 2024-09-01 10:02:36

我在 CakePHP Google Group 上发布了一个解决方案:

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

I posted a solution to this on the CakePHP Google Group:

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

Add the following to your 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); 
        } 
} 

and is used in your model validate:

        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" 
                        ) 
                ) 
       ); 
情仇皆在手 2024-09-01 10:02:36

checkUnique 可以编写为 isUn​​ique 的包装器。

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

checkUnique could just be written as a wrapper for isUnique.

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

and is used in your model validate:

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'
        )
    )
);
初心未许 2024-09-01 10:02:36

来自 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.'
    )
);

在跨多个字段制定唯一规则时,请确保在字段列表中包含原始字段。

如果列出的字段未包含在模型数据中,则将其视为空值。您可以考虑根据需要标记列出的字段。

From cakePHP 2.0 documentation:

You can validate that a set of fields are unique by providing multiple fields and set $or to false:

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

Make sure to include the original field in the list of fields when making a unique rule across multiple fields.

If a listed field isn’t included in the model data, then it’s treated as a null value. You may consider marking the listed fields as required.

寄意 2024-09-01 10:02:36

是和不是。

是的,您必须自己编写代码,但要在 CakePHP 验证组件中编写。

验证组件具有允许自定义验证规则的机制。本质上,您将函数名称放入 $validate 中(就像通常那样)。你必须定义这个函数;在这种情况下,它非常简单(只需强制执行您的双重 isUnique 要求)。

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

Yes and no.

Yes, you will have to code it yourself, but within the CakePHP validation component.

The validation component has a mechanism to allow custom validation rules. Essentially, you put a function name inside $validate (like you normally would). You do have to define the function; in this case, it's pretty simple (just enforce your double isUnique requirement).

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

猫性小仙女 2024-09-01 10:02:36

冒着因提供非 CakePHP 解决方案而遭受重创的风险,让我介绍以下内容。

在数据库中为您需要的任意数量的列创建唯一索引。

标准 SQL 语法是:

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

将“$this->Model->save()”命令放在“try/catch”块内。在“catch”块中,测试异常的错误代码。在 MySQL 中,唯一键违规是错误代码 23000,但您也应该为其他可能的错误做好准备。

它快速而简单,并且不涉及计算数组括号。

无论如何,您应该始终将数据库访问代码放置在“try/catch”块内。异常处理的一部分应包括记录任何意外的错误消息。您不能指望 CakePHP 为您做一切

At the risk of being beaten about the head and shoulders for offering a non-CakePHP solution, let me present the following.

Create a unique index in your database over however many columns you need.

Standard SQL syntax for this is:

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

Place your "$this->Model->save()" command inside of a "try/catch" block. In the "catch" block, test the exception for the error code. In MySQL, a unique key violation is error code 23000, but you should be prepared for other possible errors as well.

It's quick and simple and doesn't involve counting array parentheses.

You should always place database access code inside a "try/catch" block anyway. Part of your exception handling should include logging any unexpected error messages. You can't expect CakePHP to do everything for you.

围归者 2024-09-01 10:02:36

据我记得,您必须使用模型中的 beforeSave 方法来执行这种强制。我有一个要求,一个对象至少有 N 个 fks 集之一,我只能这样做。

编辑:尝试 此线程 看看是否有任何内容可以解决您的问题。

As far as I remember, you have to this kind of enforcement using the beforeSave method in the model. I had a requirement that an object have at least one of N fks set, and I could only do it this way.

Edit: try this thread to see if anything there solves your problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文