2016-01-11 57 views
-2

我有一个HABTM关系,如:Post <-> Tag(一个Post可以有多个标记,而其他方式相同)。使用CakePHP 2.x HABTM表单验证

这项工作由Cakephp生成的多个复选框选择。但是我希望每个帖子都至少有一个Tag,并且如果有人试图插入一个孤儿,就会抛出一个错误。

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


这是或多或少这个HABTM form validation in CakePHP问题的更新,因为我得到了同样的问题在我的CakePHP的2.7(去年CakePHP的2.x的,现在用PHP 5.3支持在2016年的数据)和可以”找到一个好方法来做到这一点。

回答

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(
      // [...] 
      ) 
     ); 
} 

这个答案用途: