【问题标题】:How to set the rules depending on the entity field?如何根据实体字段设置规则?
【发布时间】:2016-04-07 07:02:36
【问题描述】:

情况

使用 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 实体有 2 个字段,分别称为 foreign_modelforeign_model_id

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

所以一个典型的记录可以有 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));

【问题讨论】:

  • 请注意,默认情况下,当您加载 CostItem 时,foreign_model 可能会被foreign_model_id 引用的实体覆盖;将列名更改为foreign_model_name 或类似名称将消除此命名问题。 (我认为您可能还可以使用配置来更改将用于实体的属性名称,但我还没有研究过。)

标签: validation cakephp cakephp-3.0 business-rules


【解决方案1】:

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

* 需要注意的是以下都是未经测试的示例代码!

自定义规则

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

回调

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'))
    );
}

另见

【讨论】:

    猜你喜欢
    • 2020-03-04
    • 2020-05-07
    • 1970-01-01
    • 2020-09-20
    • 1970-01-01
    • 2017-11-30
    • 2018-06-25
    • 2019-01-18
    • 1970-01-01
    相关资源
    最近更新 更多