CakePHP中的isUnique验证有许多关联

CakePHP中的isUnique验证有许多关联,cakephp,Cakephp,数据库结构 我有两张桌子,用户和尼克。 在users表中,我有一个字段用户名,在nicks表中,我有一个字段nick\u名称 用户和nick之间有很多关联 在用户模型中,我正在验证在注册过程中是否只允许唯一用户名 'username must be unique' => array( 'rule' => 'isUnique', 'message' => 'username is alread

数据库结构

我有两张桌子,用户和尼克。 在users表中,我有一个字段用户名,在nicks表中,我有一个字段nick\u名称

用户和nick之间有很多关联

在用户模型中,我正在验证在注册过程中是否只允许唯一用户名

            'username must be unique' => array(
                'rule' => 'isUnique',
                'message' => 'username is already taken'

            )
但我也不想让用户注册任何以前使用过的昵称作为他们的用户名。为此

            'somebody use that name as a nickname' => array(
                'rule' => 'checkNickName',
                'message' => 'That name is already in use'
            )


但这不起作用。我应该怎么做才能让它工作?

首先找到昵称

$nick2 = $this->Nick->find('all');
然后,将生成结果数组

nick2 = array(
    0    => array(                       //first foreach
        'Nick' => array(
             nickname => 'TEST'
             )
         )
     )
因此,删除第二个foreach并使用
$name2['Nick']['nickname']

public function checkNickName(){
    $nick2 = $this->Nick->find('all');
    $nickNames = array();
    foreach($nick2 as $name2){
         array_push($nickNames,strtolower($name2['Nick']['nick_name']));
    }

    $username = strtolower($this->data['User']['username']);
    return in_array($username,$nickNames);

}

只需要使用输入表单的用户名。 在您的视图示例中:

<?php echo $this->Form->input('username', array(
                              'label' => array(
                                'text' => 'Provide your username'
                              )
                              )); ?>
验证的条件示例为唯一用户名,请使用以下选项:

编辑

  'username' => array(
    'unique' => array(
        'rule'    => array('checkNickName'),
        'message' => 'username is already taken'
    ),
   ),
在你的职能中:

public function checkNickName($check) {
  $this->loadModel('Nick');
  $username = $this->Nick->find(
      'first',
      array(
          'fields' => array(
              'Nick.id',
              'Nick.nickname'
          ),
          'conditions' => array(
              'Nick.nickname' => $check['username']
          )
      )
  );

  if(!empty($username)){
      if($this->data[$this->alias]['id'] == $username['User']['id']){
          return true;
      }else{
          return false;
      }
  }else{
      return true;
  }
}

如果我理解正确,您希望确保用户名是唯一的,但是用户名也没有被任何人用作昵称,那么为什么不使用类似的东西呢

public function checkNickIsUnique($check = array()) {
    $value = array_values($check);

    $nicknameExists = $this->Nick->find('count', array(
        'conditions' => array(
            'Nick.nick_name' => $value[0]
        )
    ));

    return ($nicknameExists > 0) ? false : true;
}
在您的用户模型中,假设它与nick直接相关,则在验证中使用它

public $validate = array(
    'username' => array(
        'isUnique' => array(
            'rule' => 'isUnique',
            'message' => 'That username has already been taken'
        ),
        'checkNickIsUnique' => array(
            'rule' => array('checkNickIsUnique'),
            'message' => 'Your username has already been taken as a nickname'
        )
    ),
);

它所做的只是将值从验证传递到方法,并检查该值是否作为昵称存在于nicks表中,如果存在,则验证失败,否则将通过。

不需要大量额外代码的更好解决方案是:

        $valid = $this->User->saveAll($this->request->data, array(
            'atomic' => false,
            'validate' => 'only'
        ));
        debug($valid);

它将验证该记录以及附加到它的所有其他记录,不需要更多的代码,只需确保在关联昵称模型中有isUnique规则。它还将使表单中的正确字段无效。

有多个用户,每个用户都有一个字段Nick,在Nick中有许多Nick\u namesOMG,我太傻了。我的原始代码正在运行。但我在本地托管的网站上编辑文件,并在服务器上托管的实时网站上测试更改。但您的代码也可以使用。:)检查用户名是否作为昵称存在似乎有点过分。当您的用户群增长,并且您可能有10000到100000个昵称时,您可能会遇到此代码的一些性能问题。请查看我的答案以获得更简单的解决方案。@HelloSpeakman yea这有点过分。我刚刚更正了问题上的第一个代码。您的答案更好。这将检查用户名的唯一性。通过
“rule”=>“isUnique”
我可以轻松做到这一点,我想要的是用户名应该等于任何昵称。表单中没有类似“昵称”的字段。在表单中,我只有一个字段,即username,用户名应等于以前使用的用户名和以前使用的昵称。understand昵称==username OP要确保User.username未在任何Nick记录(Nick.Nick_name)中使用,您仍然需要对此使用验证规则。
public function checkNickIsUnique($check = array()) {
    $value = array_values($check);

    $nicknameExists = $this->Nick->find('count', array(
        'conditions' => array(
            'Nick.nick_name' => $value[0]
        )
    ));

    return ($nicknameExists > 0) ? false : true;
}
public $validate = array(
    'username' => array(
        'isUnique' => array(
            'rule' => 'isUnique',
            'message' => 'That username has already been taken'
        ),
        'checkNickIsUnique' => array(
            'rule' => array('checkNickIsUnique'),
            'message' => 'Your username has already been taken as a nickname'
        )
    ),
);
        $valid = $this->User->saveAll($this->request->data, array(
            'atomic' => false,
            'validate' => 'only'
        ));
        debug($valid);