CakePHP中的HABTM表单验证

Sab*_*nov 5 cakephp

我有一个Projects表和一个Users表,它们通过HABTM关系链接.在"添加"新项目页面中,我有一个复选框部分,用于为新项目选择用户.我希望项目中至少有一个用户.在CakePHP中处理此问题的最佳方法是什么?

nei*_*kes 19

试试这个:

// app/models/project.php
/**
 * An additional validation check to ensure at least one User is
 * selected. Spoofs Cake into thinking that there are validation
 * errors on the Project model by invalidating a non-existent field
 * on the Project model, then also invalidates the habtm field as
 * well, so when the form is re-displayed, the error is displayed
 * on the User field.
 **/
function beforeValidate() {
  if (!isset($this->data['User']['User'])
  || empty($this->data['User']['User'])) {
    $this->invalidate('non_existent_field'); // fake validation error on Project
    $this->User->invalidate('User', 'Please select at least one user');
  }
  return true;
}
Run Code Online (Sandbox Code Playgroud)


Gui*_*iks 12

我偶然发现了同样的问题,但现在 - 3年后 - 与CakePHP 2.3.

要清楚; Group拥有并属于User.我有一个这样的表格:

// View/Groups/add.ctp
echo $this->Form->input('name');
echo $this->Form->input('User');
Run Code Online (Sandbox Code Playgroud)

使用验证规则,如user448164的答案:

// Model/Group.php
public $validate = array(
    'User' => array(
        'rule' => array('multiple', array('min' => 1)),
        'message' => 'Please select one or more users'
    )
);
Run Code Online (Sandbox Code Playgroud)

在Googling之后,这没有用,我发现这个问题仍然不是最好的解决方案.然后我尝试了几件事,发现这很好用:

// View/Groups/add.ctp
echo $this->Form->input('name');
echo $this->Form->input('Group.User');
Run Code Online (Sandbox Code Playgroud)

方式太简单的解决方案,但不得不深入研究,以找出它的工作方式.

希望有一天能帮助某人.

CakePHP 2.4.x的更新(也可能是2.3.x)

当我写这个答案时,我使用的是CakePHP 2.3.x. 当时它可以完美地用于验证和保存数据.现在,当使用CakePHP 2.4.x在新项目上应用相同的代码时,它不再起作用了.

我使用以下代码创建了一个测试用例:

$data = array(
    'User' => array(
        'Client' => array(8)
    ),
);
$this->User->create();
$this->User->saveAll($data);
Run Code Online (Sandbox Code Playgroud)

我的第一个想法是:保存所有意味着保存所有"根"模型,这对我来说实际上是有道理的.要保存比"root"更深的保存,您必须添加该deep选项.所以我最终得到了以下代码:

$data = array(
    'User' => array(
        'Client' => array(8)
    ),
);
$this->User->create();
$this->User->saveAll($data, array('deep' => true));
Run Code Online (Sandbox Code Playgroud)

奇迹般有效!快乐的编码.:)

更新(2014/03/06)

再次遇到同样的问题,在这种情况下hasMany代替habtm.好像它的行为方式相同.但我发现自己再次寻找这个答案,并感到困惑.

我想明确指出,使用它Group.User代替User输入是关键.否则它将不使用User模型验证.


小智 6

我刚刚在一个项目中看到了他自己的问题并且遇到了一个稍微优雅的解决方案,只要你只处理一个habtm关系并且你需要确保至少选中一个复选框.

例如,您正在编辑一个项目,并希望它与至少一个用户相关联

将此添加到beforeValidate()

//检查habtm模型并添加数据

  foreach($this->hasAndBelongsToMany as $k=>$v) {
   if(isset($this->data[$k][$k]))
   {
    $this->data[$this->alias][$k] = $this->data[$k][$k];
   }
  }
Run Code Online (Sandbox Code Playgroud)

在验证规则中添加以下内容:

'User' => array(
   'rule' => array('multiple', array('min' => 1)),
   'message' => 'Please select one or more users'
  )
Run Code Online (Sandbox Code Playgroud)