-1

我有一个 HABTM 关系,例如:(Post <-> Tag一个帖子可以有多个标签,反之亦然)。

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

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


这或多或少是CakePHP 问题中这个 HABTM 表单验证的更新,因为我在我的 cakephp 2.7 上遇到了同样的问题(最后一个 cakephp 2.x 现在在 2016 年支持 php 5.3)并且找不到这样做的好方法。

4

1 回答 1

1

以下是我认为目前最好的。它使用 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(
            // [...]
            )
        );
}

这个答案使用:

于 2016-01-11T13:57:48.187 回答