使用CakePHP 2.x进行HABTM表单验证

时间:2016-01-11 13:57:48

标签: php validation cakephp has-and-belongs-to-many cakephp-2.7

我有一个HABTM关系,如:Post <-> Tag(一个帖子可以有多个标签,另一种方式相同)。

使用Cakephp生成的多个复选框选项。但我希望每个帖子至少有一个标签,如果有人试图插入孤儿,则会抛出错误。

我正在寻找最干净/最像CakePHP的方法来做到这一点。

这或多或少是对这个HABTM form validation in CakePHP问题的更新,因为我在我的cakephp 2.7上遇到了同样的问题(现在最后的cakephp 2.x,在2016年的时候支持php 5.3)并且可以&# 39;找到一个好办法。

1 个答案:

答案 0 :(得分:0)

以下是我认为现在最好的内容。它使用cakephp 3.x行为进行HABTM验证。

我选择只使用模型,使用最通用的代码。

AppModel.php中,设置此beforeValidate()afterValidate()

class AppModel extends Model {
   /** @var array set the behaviour to `Containable` */
 public $actsAs = array('Containable');

   /**
    * copy the HABTM post value in the data validation scope
    * from data[distantModel][distantModel] to data[model][distantModel]
    * @return bool true
    */
 public function beforeValidate($options = array()){
   foreach (array_keys($this->hasAndBelongsToMany) as $model){
     if(isset($this->data[$model][$model]))
       $this->data[$this->name][$model] = $this->data[$model][$model];
   }

   return true;
 }

   /**
    * delete the HABTM value of the data validation scope (undo beforeValidate())
    * and add the error returned by main model in the distant HABTM model scope
    * @return bool true
    */
 public function afterValidate($options = array()){
   foreach (array_keys($this->hasAndBelongsToMany) as $model){
     unset($this->data[$this->name][$model]);
     if(isset($this->validationErrors[$model]))
       $this->$model->validationErrors[$model] = $this->validationErrors[$model];
   }

   return true;
 }
}

在此之后,您可以在模型中使用验证,如下所示:

class Post extends AppModel {

    public $validate = array(
        // [...]
        'Tag' => array(
              // here we ask for min 1 tag
            'rule' => array('multiple', array('min' => 1)),
            'required' => true,
            'message' => 'Please select at least one Tag for this Post.'
            )
        );

        /** @var array many Post belong to many Tag */
    public $hasAndBelongsToMany = array(
        'Tag' => array(
            // [...]
            )
        );
}

这个答案使用: