我想做什么?
我有三个字段(1个隐藏,一个id),用户必须完成另外两个中的一个才能通过验证
因此,如果两个字段都为空,则用户应该验证失败,如果一个字段为空则通过验证。
1 2 3
A 0 B真实
A B 0真实
A 0 0错误
我正在使用CakePHP v2.1.3 ,因此可以访问新的验证规则增强功能。
问题
我似乎无法找到同时检查两个字段的可靠方法。到目前为止,我尝试从$this->data
查看model
并发现验证一次只传递一个数据实例。所以似乎没有办法比较这些领域。
到目前为止我所拥有的
/**
* Custom validation to see if either of the two fields are set, if neither are, then we fail, if at least one is, we pass
* @param array $check
* @return boolean
*/
public function checkAttributes($check){
var_dump($check);
var_dump($this->data);
echo "<hr>";
// Check for an id value picked from a list
if(@is_numeric($check['attribute_value_id']) && isset($this->data['AdvertAttributeValue']['attribute_value_id'])){
return true;
}
// Check for a date value selected
if(@is_array($check['attribute_value_text']) && isset($this->data['AdvertAttributeValue']['attribute_value_text'])){
return true;
}
// Check for a text value
if(@is_string($check['attribute_value_text']) && isset($this->data['AdvertAttributeValue']['attribute_value_text'])){
return true;
}
return false;
}
这似乎不起作用,因为我认为它无法检查$this->data
,因为它的实例不包含所有相关字段。
数据
我还应该提一下,我正在传递一个大数字数组。所以这些字段在页面上出现多次,目前有12个维度。因此,通过$this->data
直接访问它们会很困难,因为它们不是命名维度,而是$this->data['Model'][<num>]['field'] = value
验证
public $validate = array(
'attribute_value_id'=>array(
'notempty'=>array(
'rule'=>'checkAttributes',
'message'=>'Please select a value for your attribute',
'required'=>true,
),
),
'attribute_value_text'=>array(
'notempty'=>array(
'rule'=>'checkAttributes',
'message'=>'You must enter text for this attribute',
'required'=>true,
),
)
);
数据转储
在这里,我将显示上面var_dump()
的输出。我的模型中有两个验证规则,一个用于attribute_value_id
,另一个用于attribute_value_text
// An id field selected from a list
array // $check
'attribute_value_id' => string '1' (length=1)
array // $this->data
'AdvertAttributeValue' =>
array
'attribute_value_id' => string '1' (length=1)
'id' => string '' (length=0)
// A text field
// Validating first time around on the id field
array // $check
'attribute_value_id' => string '' (length=0)
array // $this->data
'AdvertAttributeValue' =>
array
'attribute_value_id' => string '' (length=0)
'id' => string '' (length=0)
'attribute_value_text' => string '50' (length=2)
// Validating second time around on the text field
array // $check
'attribute_value_text' => string '50' (length=2)
array // $this->data
'AdvertAttributeValue' =>
array
'attribute_value_id' => string '' (length=0)
'id' => string '' (length=0)
'attribute_value_text' => string '50' (length=2)
// A date field
array // $check
'attribute_value_id' => string '' (length=0)
array // $this->data
'AdvertAttributeValue' =>
array
'attribute_value_id' => string '' (length=0)
'id' => string '' (length=0)
'attribute_value_text' =>
array
'month' => string '06' (length=2)
'day' => string '28' (length=2)
'year' => string '2012' (length=4)
答案 0 :(得分:0)
您可以使用Model :: $ data或Model :: beforeValidate()。
答案 1 :(得分:0)
saveAll()
方法只会根据需要调用saveMany()
或saveAssociated()
。默认情况下,这些方法会在保存任何数据之前尝试验证所有数据(通过调用validateMany()
)。但是,正如您在the source中看到的那样,该函数会单独验证每个项目,因此验证代码将无法访问其他记录。
据我了解,您需要在保存之前在多个记录之间进行交叉验证。虽然我从未这样做过,但这听起来像是控制器中的验证案例。您可以拨打Model::validate()
或Model::validateAll()
来确保记录的内部一致性。然后,您的控制器还可以实现交叉记录验证所需的任何逻辑。完成后,您可以禁用验证进行保存调用:
$this->myModel->saveAll($this->request->data, array('validate'=>false));
请注意,在执行此操作之前,您必须将数据设置为模型:
$this->myModel->set($this->request->data);
我意识到这会在控制器中添加许多额外的代码,理想情况下应该在模型中。我想它可以通过一个模型回调来完成,但我不确定如何。