首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Yii2行为:动态属性集值

Yii2行为:动态属性集值
EN

Stack Overflow用户
提问于 2020-08-13 11:07:58
回答 1查看 250关注 0票数 1

更新

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

代码语言:javascript
复制
 /**
     * @inheritdoc
     */
    public function behaviors()
    {
        return [
            [
                'class' => BlameableBehavior::className(),
            ],
            [
                'class' => TimestampBehavior::className(),
            ],
        ];
    }

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

代码语言:javascript
复制
DATABASE (1:1)
+----+--------------------+--------------------+------------+------------+
| id | freight_created_at | freight_updated_at | created_at | updated_at |
+----+--------------------+--------------------+------------+------------+
| XX | NULL               | NULL               | 1597223608 | 1597315472 |
+----+--------------------+--------------------+------------+------------+

然后,我需要更新另一个名为freight_created_at & freight_updated_at的专栏。这是因为在相同的记录中,所以我不能再次使用EVENT_BEFORE_INSERT。

我的行动是把运费,目标是:

如果列freight_updated_at

  • Others freight_created_at为空,则只填写freight_created_atfreight_created_at更新freight_updated_at,只填写

然后在Yii2

控制器

代码语言:javascript
复制
public function actionPutFreightDitawarkan($id) {
   $model = $this->findModel($id);
   $model->scenario = Shipment::SCENARIO_FREIGHT_DITAWARKAN;
   $model->attachBehaviors([FreightDitawarkanTimestamp::class]);
   
   ... 

}

如果我想使用一种行为,我如何实现它?到目前为止,这种行为是这样的。

行为

代码语言:javascript
复制
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);
    }
}
EN

回答 1

Stack Overflow用户

发布于 2020-08-14 09:22:37

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

但是,如果这是一个多模型的案例,那么你的方法是好的。为了满足您的要求,我也会覆盖evaluateAttributes(),例如:

代码语言:javascript
复制
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()可以简化为:

代码语言:javascript
复制
protected function getValue($event)
{
    return date('Y-m-d H:i');
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63393839

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档