yii2 behaviors ActiveRecord::EVENT_BEFORE_INSERT n

2019-07-03 22:09发布

问题:

My behavior function in my model is as follows

public function behaviors()
    {
        return [
        'timestamp' => [
        'class' => 'yii\behaviors\TimestampBehavior',
        'attributes' => [
        ActiveRecord::EVENT_BEFORE_INSERT => ['log_in_time' ],
        ActiveRecord::EVENT_BEFORE_UPDATE => ['log_in_time'],
        ],
        'value' => new Expression('NOW()'),
        ],
        ];
    }
/**
     * validation rules
     */

public function rules()
{
    return [

            ['username','filter', 'filter' => 'trim'],
            ['username','required'],
            //['username','unique'],
            ['username','string', 'min' => 2, 'max' => 255],
            ['password','required'],

        ];
    }

/* Your model attribute labels */
public function attributeLabels()
{
    return [
    /* Your other attribute labels */
    ];
}

public function scenarios()
    {
        $scenarios = parent::scenarios();
        $scenarios['login'] = ['username','log_in_time'];//Scenario Values Only Accepted
        return $scenarios;
    }

But it is not updating the log_in_time column . log_in_time is DATETIME . The value getting inserted is 0000-00-00 00:00:00 .What is the problem ?

回答1:

Are you by any chance overwriting beforeSave (or beforeInsert or beforeUpdate) in that particular model? If you do then you have to call something like

public function beforeSave($insert)
{
    if (parent::beforeSave($insert)) {
        ............
        return true;
    }
    return false;
}

I recently did something similar and spent some good time researching this only to realize that I did not call the parent before save.

If you use AttributeBehavior instead of TimestampBehavior and do exactly what you did, I believe it will work.

public function behaviors()
    {
        return [
        'timestamp' => [
        'class' => 'yii\behaviors\AttributeBehavior',
        'attributes' => [
        ActiveRecord::EVENT_BEFORE_INSERT => ['log_in_time' ],
        ActiveRecord::EVENT_BEFORE_UPDATE => ['log_in_time'],
        ],
        'value' => new Expression('NOW()'),
        ],
        ];
    }

Or you can try setting createdAtAttribute and $updatedAtAttribute to 'log_in_time' in the TimestampBehavior, that should also work.

     public function behaviors()
            {
                return [
                'timestamp' => [
                'class' => 'yii\behaviors\TimestampBehavior',
'createdAtAttribute' =>  'log_in_time',
'updatedAtAttribute' =>  'log_in_time',
                ],
                ];
            }

I am not sure why it does not work like you posted.

This works for me 100%

/**
 * @inheritdoc
 */
public function behaviors()
{
    return [
        'blameable' => [
            'class' => BlameableBehavior::className(),
            'attributes' => [
                BaseActiveRecord::EVENT_BEFORE_INSERT => ['create_by', 'update_by'],
                BaseActiveRecord::EVENT_BEFORE_UPDATE => 'update_by'
            ],                
        ],
        'timestamp' => [
            'class' => TimestampBehavior::className(),
            'attributes' => [
                BaseActiveRecord::EVENT_BEFORE_INSERT => ['create_time', 'update_time'],
                BaseActiveRecord::EVENT_BEFORE_UPDATE => 'update_time',
            ],
            'value' => new Expression('NOW()'),
        ],
    ];
}