5

I am trying to update some fields in yii 1.1 using the following rules, but it is not working.

public function rules()
{
    return [
       ['CreatedOn','default','value'=>time(),'isEmpty'=>true,'on'=>'insert'],
       ['CreatedBy','default','value'=>\Yii::$app->user->identity->id,'isEmpty'=>true,'on'=>'insert'],
       ['ModifiedOn','default','value'=>time(),'isEmpty'=>true,'on'=>'update'],
       ['ModifiedBy','default','value'=>\Yii::$app->user->identity->id,'isEmpty'=>true,'on'=>'update'],
    ];
}

I am looking to update CreatedBy and CreatedOn when inserting, and ModifiedBy and ModifiedOn when updating.

5
  • 2
    Welcome to Stack Overflow! I've taken a shot at making your question easier to follow by editing the grammar and moving some things around. Commented Mar 10, 2015 at 13:13
  • @nadeem do you really think that this is yii 1.1? Commented Mar 10, 2015 at 15:00
  • 2
    This seems to be for Yii2+ Commented Jun 14, 2015 at 18:39
  • @MuhammadRiyaz You're of course right. Yii::$app construction is used only in Yii2. Yii1 equivalent is Yii::app(). OP should decide, edit question and properly tag it. Commented Jul 23, 2015 at 6:57
  • edited. Thanks for pointing out Commented Apr 26, 2017 at 20:13

3 Answers 3

13

From soju's excellent answer, with Yii2:

By default, a model supports only a single scenario named default

You should therefore set the scenario manually in your controller i.e:

$model->scenario = 'insert';

You could also use when instead of on i.e:

['CreatedOn', 'default', 'value'=>time(), 'isEmpty'=>true, 'when'=>
    function($model) { return $model->isNewRecord; }
],
['ModifiedOn', 'default', 'value'=>time(), 'isEmpty'=>true, 'when'=>
    function($model) { return !$model->isNewRecord; }
],

An alternative to setting them in rules() would be to use beforeSave() to set them:

public function beforeSave($insert) {
    if ($insert) {
        $this->CreatedBy = \Yii::$app->user->identity->id;
        $this->CreatedOn = time();
    } else {
        $this->ModifiedBy = \Yii::$app->user->identity->id;
        $this->ModifiedOn = time();
    }
    return parent::beforeSave($insert);
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your reply i tried first solution but still not working but i tried 2nd same (beforeSave()) solution as yours and fixed but i am still trying for first solution
@topher 'isEmpty'=>true overrides the check if the field is empty .. and says it always is. this is not needed for the CreatedOn rule. the 'when' condition you use is also not needed in both cases. See my answer below
2

This is the correct way to do it:

Behaviors:

public function behaviors()
    {
        return [
            'timestamp' => [
                'class' => TimestampBehavior::className(),
                'attributes' => [
                    ActiveRecord::EVENT_BEFORE_INSERT => 'created_on',
                    ActiveRecord::EVENT_BEFORE_UPDATE => 'modified_on',
                    ActiveRecord::EVENT_BEFORE_DELETE => 'deleted_at',
                ],
                'value' => function () {
                    return date('Y-m-d H:i:s');
                }
            ],
            [
                'class' => BlameableBehavior::className(),
                'createdByAttribute' => 'created_by_id',
                'updatedByAttribute' => 'updated_by_id',
            ],
        ];
    }

If you need just a simple rule for default value, this is enough:

 public function rules()
    {
        return [
            ['CreatedOn','default','value'=>time()],
            ['ModifiedOn','default','value'=>time(),'isEmpty'=>true],
        ...
        ]
    }

The 'isEmpty'=>true option override the default isEmpty() function and returns true (it is always seen as empty) dues it is always populated with time()

Comments

0

For Yii2 version 2.0.8 from April 2016 I had an error with 'isEmpty'=>true because according to documentation it expects a function so you must to do like this:'isEmpty' => function ($value) {return true;}.

When you use this solution you get a value for ModifiedBy even on create and I believe that was not an intention. It is possible to write isEmpty to return true in case of an update but I simply used 'when' because it is much more readable for me. So, my solution for rules in a model was :

    ['CreatedBy', 'default', 'value' => Yii::$app->user->id],
    ['ModifiedBy', 'default', 'value' => Yii::$app->user->id,
         'when' => function ($model) { return !$model->isNewRecord;}],

As a side note for this question is that for timestamps you should rely on database to fill them, CreatedOn with default value and a before update trigger for ModifiedOn.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.