stampede76
stampede76

Reputation: 1631

Yii model isNewRecord false due to constructor

In Yii ActiveRecord, is it possible to set an attribute in a model constructor and still have the model's isNewRecord property remain true?

I have a model constructor to create a private attribute to hold a PHPPass Password hash instance. When I do this, it sets the isNewRecord property to false, even though the record is created new.

I tried a workaround with call to setIsNewRecord(true) in the constructor if the id attribute is greater than zero, but it appears attributes are not available in the constructor.

I had to remove the constructor, and make the statement in each method requiring phpass.

Constructor for User model:

public function __construct(){
    $this->phpass=new PasswordHash(Yii::app()->params['phpass']['iteration_count_log2'], Yii::app()->params['phpass']['portable_hashes']);
}

User model init and isNewRecord condition in controller

public function actionEdit($id = null)
{

    $myModel = new User();       
    echo $myModel->isNewRecord;   //false due to constructor
}

Upvotes: 3

Views: 2800

Answers (2)

user133408
user133408

Reputation:

When ovveriding contstructor make sure to call parent constructor. Always call parent constructor when ovveriding, unless you know what you are doing.

public function __construct($scenario = 'insert'){
    parent::__construct($scenario);
    $this->phpass=new PasswordHash(Yii::app()->params['phpass']['iteration_count_log2'], Yii::app()->params['phpass']['portable_hashes']);
}

Also phpass can be stored as static property, you don't need a new instance of phpass for each active record instance.

EDIT: Thanks @Kevin for link to question about ovverding constructors.

One more important note to add: Remember to pass parameters to constructor. In Yii model classes there is $scenario param with default value insert. When you ovveride constructor without passing this argument, there will be always insert scenario, and there will not be any error message about missing param, because it has default value. I Updated code with $scenario.

Upvotes: 5

Michael Härtl
Michael Härtl

Reputation: 8587

In general you should avoid to override the constructor in Yii classes. Most components provide a init() method instead which is the right place for code like in your example.

The difference is, that for application components the object will already have all configuration applied. That's not relevant in your case but still it's good practice to use init() instead of __construct().

Upvotes: 3

Related Questions