Behaviors Not Working

I’m trying to get the “create_at” and “update_at” values populated using behaviors.

I’ve removed those fields from the required section.

I’ve tried using the code below “1. This is not working” and using the one below “2. This is not working either”

I’m pretty sure I’ve done everything by the book and this might be a bug, but if I’m not please help me.

This is the test model:


<?php


namespace backend\models;


use Yii;


/**

 * This is the model class for table "test".

 *

 * @property integer $id

 * @property string $name

 * @property integer $create_at

 * @property integer $update_at

 */

class Test extends \yii\db\ActiveRecord

{

    /**

     * @inheritdoc

     */

    public static function tableName()

    {

        return 'test';

    }


    /**

     * @inheritdoc

     */

    public function rules()

    {

        return [

            [['name'], 'required'],

            [['create_at', 'update_at'], 'integer'],

            [['name'], 'string', 'max' => 255]

        ];

    }


    /**

     * @inheritdoc

     */

    public function attributeLabels()

    {

        return [

            'id' => 'ID',

            'name' => 'Name',

            'create_at' => 'Create At',

            'update_at' => 'Update At',

        ];

    }

}



This is the test controller:


<?php


namespace backend\controllers;


use Yii;

use backend\models\Test;

use backend\models\search\TestSearch;

use yii\web\Controller;

use yii\web\NotFoundHttpException;

use yii\filters\VerbFilter;

use yii\db\ActiveRecord;

use yii\db\Expression;

use yii\behaviors\TimestampBehavior;


/**

 * TestController implements the CRUD actions for Test model.

 */

class TestController extends Controller

{

    public function behaviors()

    {

        return [

            'timestamp' => [

                // 1. This is not working

                // 'class' => TimestampBehavior::className(),

                // 'attributes' => [

                //     ActiveRecord::EVENT_BEFORE_INSERT => ['create_at', 'update_at'],

                //     ActiveRecord::EVENT_BEFORE_UPDATE => ['update_at']

                // ]

                

                // 2. This is not working either

                'class' => TimestampBehavior::className(),

                'createdAtAttribute' => 'create_at',

                'updatedAtAttribute' => 'update_at',

                'value' => new Expression('NOW()'),

            ],

            'verbs' => [

                'class' => VerbFilter::className(),

                'actions' => [

                    'delete' => ['post'],

                ],

            ],

        ];

    }


    /**

     * Lists all Test models.

     * @return mixed

     */

    public function actionIndex()

    {

        $searchModel = new TestSearch();

        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);


        return $this->render('index', [

            'searchModel' => $searchModel,

            'dataProvider' => $dataProvider,

        ]);

    }


    /**

     * Displays a single Test model.

     * @param integer $id

     * @return mixed

     */

    public function actionView($id)

    {

        return $this->render('view', [

            'model' => $this->findModel($id),

        ]);

    }


    /**

     * Creates a new Test model.

     * If creation is successful, the browser will be redirected to the 'view' page.

     * @return mixed

     */

    public function actionCreate()

    {

        $model = new Test();


        if ($model->load(Yii::$app->request->post()) && $model->save()) {

            return $this->redirect(['view', 'id' => $model->id]);

        } else {

            return $this->render('create', [

                'model' => $model,

            ]);

        }

    }


    /**

     * Updates an existing Test model.

     * If update is successful, the browser will be redirected to the 'view' page.

     * @param integer $id

     * @return mixed

     */

    public function actionUpdate($id)

    {

        $model = $this->findModel($id);


        if ($model->load(Yii::$app->request->post()) && $model->save()) {

            return $this->redirect(['view', 'id' => $model->id]);

        } else {

            return $this->render('update', [

                'model' => $model,

            ]);

        }

    }


    /**

     * Deletes an existing Test model.

     * If deletion is successful, the browser will be redirected to the 'index' page.

     * @param integer $id

     * @return mixed

     */

    public function actionDelete($id)

    {

        $this->findModel($id)->delete();


        return $this->redirect(['index']);

    }


    /**

     * Finds the Test model based on its primary key value.

     * If the model is not found, a 404 HTTP exception will be thrown.

     * @param integer $id

     * @return Test the loaded model

     * @throws NotFoundHttpException if the model cannot be found

     */

    protected function findModel($id)

    {

        if (($model = Test::findOne($id)) !== null) {

            return $model;

        } else {

            throw new NotFoundHttpException('The requested page does not exist.');

        }

    }

}



And this is the error that I get:


Integrity constraint violation – yii\db\IntegrityException


SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'create_at' cannot be null

The SQL being executed was: INSERT INTO `test` (`name`, `create_at`, `update_at`) VALUES ('some name', NULL, NULL)

Error Info: Array

(

    [0] => 23000

    [1] => 1048

    [2] => Column 'create_at' cannot be null

)

↵

Caused by: PDOException


SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'create_at' cannot be null


in /media/sf_sandbox/yii2test/vendor/yiisoft/yii2/db/Command.php at line 768

and this is the sql for that MySQL table:


CREATE TABLE IF NOT EXISTS `test` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `name` varchar(255) NOT NULL,

  `create_at` int(11) NOT NULL,

  `update_at` int(11) NOT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;



why it’s in controller and not in ActiveRecord?

Thanks, that did it.

I’ve removed the code from the behaviors of the controller and added them into the model and it worked.

Thanks a lot!!

If anyone else runs into the problem, this is how the code looks like and it is working:

The model:


<?php


namespace backend\models;


use Yii;

use yii\behaviors\TimestampBehavior;

use yii\db\ActiveRecord;


/**

 * This is the model class for table "test".

 *

 * @property integer $id

 * @property string $name

 * @property integer $create_at

 * @property integer $update_at

 */

class Test extends \yii\db\ActiveRecord

{

    /**

     * @inheritdoc

     */

    public static function tableName()

    {

        return 'test';

    }


    /**

     * @inheritdoc

     */

    public function behaviors()

    {

        return [

            'timestamp' => [

                'class' => TimestampBehavior::className(),

                'attributes' => [

                    ActiveRecord::EVENT_BEFORE_INSERT => ['create_at', 'update_at'],

                    ActiveRecord::EVENT_BEFORE_UPDATE => ['update_at']

                ]

            ],

        ];

    }


    /**

     * @inheritdoc

     */

    public function rules()

    {

        return [

            [['name'], 'required'],

            [['create_at', 'update_at'], 'integer'],

            [['name'], 'string', 'max' => 255]

        ];

    }


    /**

     * @inheritdoc

     */

    public function attributeLabels()

    {

        return [

            'id' => 'ID',

            'name' => 'Name',

            'create_at' => 'Create At',

            'update_at' => 'Update At',

        ];

    }

}



The controller:


<?php


namespace backend\controllers;


use Yii;

use backend\models\Test;

use backend\models\search\TestSearch;

use yii\web\Controller;

use yii\web\NotFoundHttpException;

use yii\filters\VerbFilter;


/**

 * TestController implements the CRUD actions for Test model.

 */

class TestController extends Controller

{

    public function behaviors()

    {

        return [

            'verbs' => [

                'class' => VerbFilter::className(),

                'actions' => [

                    'delete' => ['post'],

                ],

            ],

        ];

    }


    /**

     * Lists all Test models.

     * @return mixed

     */

    public function actionIndex()

    {

        $searchModel = new TestSearch();

        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);


        return $this->render('index', [

            'searchModel' => $searchModel,

            'dataProvider' => $dataProvider,

        ]);

    }


    /**

     * Displays a single Test model.

     * @param integer $id

     * @return mixed

     */

    public function actionView($id)

    {

        return $this->render('view', [

            'model' => $this->findModel($id),

        ]);

    }


    /**

     * Creates a new Test model.

     * If creation is successful, the browser will be redirected to the 'view' page.

     * @return mixed

     */

    public function actionCreate()

    {

        $model = new Test();


        if ($model->load(Yii::$app->request->post()) && $model->save()) {

            return $this->redirect(['view', 'id' => $model->id]);

        } else {

            return $this->render('create', [

                'model' => $model,

            ]);

        }

    }


    /**

     * Updates an existing Test model.

     * If update is successful, the browser will be redirected to the 'view' page.

     * @param integer $id

     * @return mixed

     */

    public function actionUpdate($id)

    {

        $model = $this->findModel($id);


        if ($model->load(Yii::$app->request->post()) && $model->save()) {

            return $this->redirect(['view', 'id' => $model->id]);

        } else {

            return $this->render('update', [

                'model' => $model,

            ]);

        }

    }


    /**

     * Deletes an existing Test model.

     * If deletion is successful, the browser will be redirected to the 'index' page.

     * @param integer $id

     * @return mixed

     */

    public function actionDelete($id)

    {

        $this->findModel($id)->delete();


        return $this->redirect(['index']);

    }


    /**

     * Finds the Test model based on its primary key value.

     * If the model is not found, a 404 HTTP exception will be thrown.

     * @param integer $id

     * @return Test the loaded model

     * @throws NotFoundHttpException if the model cannot be found

     */

    protected function findModel($id)

    {

        if (($model = Test::findOne($id)) !== null) {

            return $model;

        } else {

            throw new NotFoundHttpException('The requested page does not exist.');

        }

    }

}