CakePHP中的isUnique验证有很多关联

时间:2014-10-28 15:17:19

标签: cakephp

数据库结构

我有两个表,用户 nicks 。 在用户表中,我有一个字段用户名,在 nicks 表中,我有一个字段 nick_name

用户 nicks

之间存在 hasMany 关联
    public $hasMany = array(
        'Nick' => array(
            'className' => 'Nick',
            'foreignKey' => 'user_id',
            'dependent' => true
        )

    );

用户模型中,我通过

验证在注册时仅允许唯一的用户名
            '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'
            )

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

        }

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

    }

但那不起作用。我该怎么做呢?

4 个答案:

答案 0 :(得分:2)

如果我理解正确,你想确保用户名是唯一的,但是用户名也没有被任何人用作昵称,为什么不使用这样的东西?

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表中的昵称存在,如果它存在则验证失败,否则它将通过。

答案 1 :(得分:0)

首先找到昵称。

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

}

答案 2 :(得分:0)

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

<?php echo $this->Form->input('username', array(
                              'label' => array(
                                'text' => 'Provide your username'
                              )
                              )); ?>

并在您的模型中需要更改

      'username' => array(
        'nonEmpty' => array(
            'rule' => array('notEmpty'),
            'message' => 'not empty please',
            'allowEmpty' => false
        ),
        'unique' => array(
            'rule'    => array('isUniqueUsername'),
            'message' => 'username is already taken'
        ),
       ),


        'nickname' => array(
           'nonEmpty' => array(
              'rule' => array('notEmpty'),
              'message' => 'not empty',
              'allowEmpty' => false
            ),
           'unique' => array(
              'rule'    => array('checkNickName'),
              'message' => 'That name is already in use'
            )
        )

您的条件示例是验证是唯一的用户名,请使用:

修改

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

答案 3 :(得分:0)

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

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

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