Kohana ORM的验证是使用rules
function rules()
{
return array(
'username' => array(
array('not_empty'),
array(array($this, 'availability')),
)
);
}
我正在努力使用$_serialize_columns
验证JSON编码列。
class Model_Admin extends ORM {
protected $_belongs_to = array();
protected $_has_many = array(
'plans' => array(),
'groups' => array(),
'transactions' => array(),
'logins' => array()
);
protected $_serialize_columns = array('data');
/**
* @param array $data
* @param Validation $validation
*
* @return bool
*/
public function data($data, $validation)
{
return
Validation::factory(json_decode($data, TRUE))
// ... rules ...
->check();
}
public function rules()
{
return array(
'data' => array(
array(array($this, 'data'), array(':value',':validation')
)
);
}
}
被编码的数组是:
array(
'name' => '',
'address' => '',
'phone' => '',
'postalcode' => ''
);
data
方法接收json编码数据,因为ORM在进行验证之前运行过滤器,因此我需要将其转换回关联数组,然后创建一个新的验证对象以专门检查该数组的内容。因为我无法合并来自另一个Validation
实例的Validation
规则
答案 0 :(得分:0)
更新了答案
由于save()
导致检查内部模型验证对象,因此必须使用第二个验证对象。这意味着将忽略从验证规则检查的验证对象中添加的规则(Validation->check()
在循环之前将规则导入本地范围。)
由于数据本身在技术上是另一个对象(在对象关系的意义上,它有自己的数据集需要验证),理想的解决方案是找到一种方法来创建一个保存数据的真实模型。
使用正确的数据库列定义保存数据还有许多其他好处,尤其是如果您需要执行数据属性查找,进行原位更改等(否则需要对数据列进行反序列化,并在所有行中保存)
有一些替代方案,但他们觉得像我一样:
创建一个代表数据对象并向其添加规则的模型,使用check()
验证数据(问题:需要大量维护,没有实际表格意味着必须手动填充列)定义的)。
在Admin模型中将数据设置为实际列,并使用过滤器将其转换为set上的数据列(问题:同样,必须手动定义列并从保存操作中排除其他列) )。
我希望这有一些用处。
原始答案
Kohana ORM save()
方法允许包含“额外”验证对象,该对象合并到主ORM验证对象命名空间中。
简要记录here。
如果我理解正确,我认为您正在寻找这样的事情:
// another script, e.g., a controller
// Create the model
$admin = ORM::factory('Admin');
// $data = the data as an array, before serialization ...
$extra_validation = Validation::factory($data)
// add ->rule() calls here, but DO NOT chain ->check()
;
// Set $data in the model if it is going to be saved, e.g., $admin->data = $data;
// Set other data... e.g., $admin->foo = 'bar';
// Save the model
try {
$admin->save($extra_validation);
}
catch (ORM_Validation_Exception $e)
{
// Manipulate the exception result
}
虽然在此示例中您仍必须创建另一个验证对象,但现在您可以捕获单个块中的所有异常。如果您使用i18n消息提供人类可读的错误消息,我建议您使用var_dump()
或类似$e->errors()
来检查命名空间。您应该会在响应中找到名为“_external”的命名空间。