如何根据实体字段设置规则?

时间:2016-04-07 07:02:36

标签: validation cakephp cakephp-3.0 business-rules

情况

使用Cake 3.2.6

在我的CostItemsTable中,

我有一个buildRules功能

/**
 * Returns a rules checker object that will be used for validating
 * application integrity.
 *
 * @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
 * @return \Cake\ORM\RulesChecker
 */
public function buildRules(RulesChecker $rules)
{

    $rules->add($rules->existsIn(['foreign_model_id'], 'ForeignModels'));
    return $rules;
}

我想要什么

我的CostItems实体有两个名为foreign_modelforeign_model_id的字段。

foreign_model_id充当外键。 foreign_model充当将成为CostItems表的Parent的表。

因此,典型记录可以foreign_model为GeneralCostCategories,foreign_model_id为1。

我尝试了什么

我尝试在buildRules函数中记录$ this,但我发现没有什么有用的东西允许我动态更改此规则。

   $rules->add($rules->existsIn(['foreign_model_id'], 'ForeignModels'));

   $rules->add($rules->existsIn(['foreign_model_id'], $entity->foreign_model));

1 个答案:

答案 0 :(得分:2)

有多种方法可以解决这个问题,其中有两种方法。

*应该注意以下是所有未经测试的示例代码!

自定义规则

您可以实现一个自定义规则,作为回调,或作为规则类,将实体传递到该规则,然后使用来自实体的数据相应地运行exists检查。

<强>回调

use Cake\Datasource\EntityInterface;
use Cake\ORM\Rule\ExistsIn;

// ...

$rules->add(
    function (EntityInterface $entity, array $options) {
        $check = new ExistsIn(['foreign_model_id'], $entity->get('foreign_model'));
        return $check($entity, $options);
    },
    '_existsIn',
    [
        'errorField' => 'foreign_model_id',
        'message' => __d('cake', 'This value does not exist')
    ]
);

自定义规则类,src / Model / Rule / MyExitsIn.php

namespace App\Model\Rule;

use Cake\Datasource\EntityInterface;
use Cake\ORM\Rule\ExistsIn;

class MyExistsIn extends ExistsIn
{
    public function __construct($fields)
    {
        parent::__construct($fields, null);
    }

    public function __invoke(EntityInterface $entity, array $options)
    {
        $this->_repository = $entity->get('foreign_model');
        return parent::__invoke($entity, $options);
    }
}
use App\Model\Rule\MyExistsIn;

// ...

$rules->add(
    new MyExistsIn(['foreign_model_id']),
    '_existsIn',
    [
        'errorField' => 'foreign_model_id',
        'message' => __d('cake', 'This value does not exist')
    ]
);

即时构建规则

或者使用接收实体的Model.beforeRules事件,并动态修改规则检查器对象。

您的表类中的

use Cake\Datasource\EntityInterface;
use Cake\Event\Event;

// ...

public function beforeRules(Event $event, EntityInterface $entity, \ArrayObject $options, $operation)
{
    /* @var $rulesChecker \Cake\ORM\RulesChecker */
    $rulesChecker = $this->rulesChecker();
    $rulesChecker->add(
        $rulesChecker->existsIn(['foreign_model_id'], $entity->get('foreign_model'))
    );
}

另见