Yii2行为:动态属性设置值

问题描述

更新

我有一条使用Yii插入的记录 我的模型名为Shipment,已实现:

 /**
     * @inheritdoc
     */
    public function behaviors()
    {
        return [
            [
                'class' => BlameableBehavior::className(),],[
                'class' => TimestampBehavior::className(),];
    }

假设这些是数据库中的记录,如下所示:

DATABASE (1:1)
+----+--------------------+--------------------+------------+------------+
| id | freight_created_at | freight_updated_at | created_at | updated_at |
+----+--------------------+--------------------+------------+------------+
| XX | NULL               | NULL               | 1597223608 | 1597315472 |
+----+--------------------+--------------------+------------+------------+

然后,我需要更新另一列freight_created_atfreight_updated_at。这是因为在同一记录中,所以我不能再次使用EVENT_BEFORE_INSERT。

我对PUT货运的行动,目标是:

  1. 如果列freight_created_at为空,请填写 freight_created_atfreight_updated_at
  2. 其他人仅更新freight_updated_at

然后在Yii2中

CONTROLLER

public function actionPutFreightDitawarkan($id) {
   $model = $this->findModel($id);
   $model->scenario = Shipment::SCENARIO_FREIGHT_DITAWARKAN;
   $model->attachBehaviors([FreightDitawarkanTimestamp::class]);
   
   ... 

}

如果我想使用某种行为,该如何实现?到目前为止,行为看起来像这样。

行为

class FreightDitawarkanTimestamp extends AttributeBehavior {

    public $createdAtAttribute = 'freight_created_at';
    public $updatedAtAttribute = 'freight_updated_at';
    public $value;

    public function init() {
        if (empty($this->attributes)) {
            $this->attributes = [
                BaseActiveRecord::EVENT_BEFORE_UPDATE =>
                    [
                        $this->createdAtAttribute,$this->updatedAtAttribute
                    ]
            ];
        }
        parent::init();

    }
    protected function getValue($event) {
        $this->value = date('Y-m-d H:i');
        return parent::getValue($event);
    }
}

解决方法

仅当您想在多个模型中使用该行为时,该行为才适用于此;否则,您可以仅使用$model->touch()(即$model->touch('freight_created_at')),因为您可以通过已附加的TimestampBehavior访问该方法。

但是,如果这是多模型案例,那么您的方法确实不错。我也将覆盖evaluateAttributes()以满足您的要求,例如:

public function evaluateAttributes($event)
{
    if ($this->skipUpdateOnClean
        && $event->name == ActiveRecord::EVENT_BEFORE_UPDATE
        && empty($this->owner->dirtyAttributes)
    ) {
        return;
    }

    if (!empty($this->attributes[$event->name])) {
        $attributes = (array) $this->attributes[$event->name];
        $value = $this->getValue($event);
        foreach ($attributes as $attribute) {
            if ($attribute === $this->createdAtAttribute && !empty($this->owner->$attribute)) {
                // don't update "created_at" value if already set
                continue;
            }
            $this->owner->$attribute = $value;
        }
    }
}

getValue()可以简化为:

protected function getValue($event)
{
    return date('Y-m-d H:i');
}

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...