如何在ORM中验证$ _serialize_column的Kohana

时间:2012-12-15 16:47:28

标签: json validation kohana kohana-3 kohana-orm

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规则

1 个答案:

答案 0 :(得分:0)

更新了答案

由于save()导致检查内部模型验证对象,因此必须使用第二个验证对象。这意味着将忽略从验证规则检查的验证对象中添加的规则(Validation->check()在循环之前将规则导入本地范围。)

由于数据本身在技术上是另一个对象(在对象关系的意义上,它有自己的数据集需要验证),理想的解决方案是找到一种方法来创建一个保存数据的真实模型。

使用正确的数据库列定义保存数据还有许多其他好处,尤其是如果您需要执行数据属性查找,进行原位更改等(否则需要对数据列进行反序列化,并在所有行中保存)

有一些替代方案,但他们觉得像我一样:

  1. 创建一个代表数据对象并向其添加规则的模型,使用check()验证数据(问题:需要大量维护,没有实际表格意味着必须手动填充列)定义的)。

  2. 在Admin模型中将数据设置为实际列,并使用过滤器将其转换为set上的数据列(问题:同样,必须手动定义列并从保存操作中排除其他列) )。

  3. 我希望这有一些用处。

    原始答案

    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”的命名空间。