Yii2: TimestampBehavior not working

Created on 22 Mar 2018  路  27Comments  路  Source: yiisoft/yii2

The project and this model is already six months old and all worked fine before, but suddenly the TimestampBehavior broke down. The database writes all the time zeros (in those fields where there should be time). I did not change anything related to this. It feels like a crash somewhere inside the framework...

Important! I noticed in the debugger that after saving the model the fields it is not empty !!! But the database still writes zeros. It's very strange...

Here is my model:

/**
 * @property integer $id
 * @property integer $category_id
 * @property integer $user_id
 * @property integer $status_id
 * @property string $name
 * @property string $text
 * @property integer $created_at
 * @property integer $updated_at
 */
class Article extends ActiveRecord {
    public static function tableName() {
        return '{{%article}}';
    }

    public function behaviors() {
        return [
            'timestamp' => TimestampBehavior::class,
        ];
    }

    public function rules() {
        return [
            ['id', 'safe'],
            [['name', 'category_id'], 'required'],
            ['user_id', 'default', 'value' => Yii::$app->user->id],
        ];
    }
}

Yii 2.0.14

question

All 27 comments

Thank you for your question.
In order for this issue tracker to be effective, it should only contain bug reports and feature requests.

We advise you to use our community driven resources:

If you are confident that there is a bug in the framework, feel free to provide information on how to reproduce it. This issue will be closed for now.

_This is an automated comment, triggered by adding the label question._

I inform you about the bug. It's not a question!

For version 2.0.15 the problem is also relevant.

@larryli What have I done wrong? What did not specify all the fields (attributes, value, etc.)? But this is not necessarily as far as I know. As fields for dates at me are called by default created_at and updated_at. Before it all worked out that way normal!

From the comment to the behaviours method:

The return value of this method should be an array of behavior objects or configurations indexed by behavior names. A behavior configuration can be either a string specifying the behavior class or an array of the following structure:

@i-panov I see that you are using behaviour differently from documentation:

http://www.yiiframework.com/doc-2.0/yii-behaviors-timestampbehavior.html

    return [
        TimestampBehavior::className(),
    ];

or if you have customized the attributes:

    return [
        [
            'class' => TimestampBehavior::className(),
            'createdAtAttribute' => 'create_time',
            'updatedAtAttribute' => 'update_time',
            'value' => new Expression('NOW()'),
        ],
    ];

@FabrizioCaldarelli If you mean that I specified class instead of className(), then you yourself deprecated this method!

@deprecated since 2.0.14. On PHP >=5.5, use ::class instead.

I use PHP 5.6

No, I refer to structure. You used 'timestamp' key and TimestampBehavior::class value, I posted an array with only TimestampBehavior::className() value or 'class' key and TimestampBehavior::className() value.

@FabrizioCaldarelli Once again I repeat:

From the comment to the behaviours method:
The return value of this method should be an array of behavior objects or configurations indexed by behavior names. A behavior configuration can be either a string specifying the behavior class or an array of the following structure:

So, judging by your documentation, I can just use the class name instead of an array. And the timestamp key is needed for the detachBehavior capability.

@i-panov Did you use beforeSave function in Article like this:

    public function beforeSave($insert)
    {
        // @bug: do not call parent::beforeSave($insert)
        return true;
    }

@larryli No, I do not use beforeSave.

@i-panov If not, you can make a log in Article::beforeSave:

    public function beforeSave($insert)
    {
        $return = parent::beforeSave($insert);
        Yii::info("created_at: {$this->created_at}, updated_at: {$this->updated_at}");
        return $return;
    }

@larryli As I said before

Important! I noticed in the debugger that after saving the model the fields it is not empty !!! But the database still writes zeros. It's very strange...

created_at: 1521796945, updated_at: 1521796945

@i-panov TimestampBehavior are working fine.

Please check again at Article::afterSave. If created_at not zero, someone may update after you write date.

What is your DB column data type?

@i-panov We have a unit test that verifies, that behavior works as it should. Could you change it so it fails?

@larryli And in beforeSave and inafterSave, the fields created_at andupdated_at are not empty. I'm sure that these fields are not rewritten anywhere (search PHPStorm does not find such places).

@berosoboy int

Enable db profiling and see the generated INSERT/UPDATE query in debug panel or logs.

@berosoboy I have a yii-debug-toolbar and there are all the logs. Now I looked at the insert query: there are no fields created_at and updated_at. At all. I do not know how to explain it. In beforeSave they are setted, but in the query they are not...

Do this:
In your beforeSave, check the result of $this->getDirtyAttributes();

@berosoboy The created_at and updated_at attributes are not there.

FUUUUUUUUUUCK!!!!! I think I understood what's wrong ... The problem was again in your unobvious infrastructure! I called the save(true, ['name', 'category_id', 'user_id', 'status_id']) method. But I somehow thought that this array specifies which attributes should be validated and which ones do not! And now I read that it indicates which attributes should be saved ...

Thank you all for your help. :) You can close the issue.

You're welcome :D

Simply there the first parameter goes the flag runValidation and by itself the conclusion suggests that the second parameter specifies attributes for validation... This is much more logical. I would do so in your place. And what for to specify attributes which it is necessary to save I generally do not know... After all, they can simply not be setted.

Or, remove the flag runValidation, because there is still a method validate in which already an array of attributes is also passed indicating which ones should be validated.

The save() method is intended to save the model. In my opinion the method params are OK.

Was this page helpful?
0 / 5 - 0 ratings