Using Getter & Validation Rule For Virtual Attribute, Not Working

Hello. I have a form with a virtual attribute, which I need to be validated in rules()

I know if I want to validate the virtual attribute, it must to be declarated as ‘public $virtual_attribute;’ in the model.

So, I also know that virtual attributes declarated as ‘public $virtual_attribute;’ in the model class, its values couldn’t be getted by using ‘public getVirtual_attribute(){ return ‘hello’; }’. I don’t know why, but getters not works with declarated virtual attributes.

In this case… What can I do to use a virtual attribute in order to obtain it value with a getter, and also to be validated in rules()?

The simplest thing is to overload the validate() method and do it manually. You probably do the value assignment manually anyway.

I wouldn’t go for more generic solution because I think this happens rarely and there are lot more consequences to think of to design such mechanisms properly.

Virtual attributes should be use as same as other attributes.

Here is example I have. In new user create page, we always request to accept password entered, but we only receive one password in the database.

So I defined $user_password2 as virtual attributes for the User.




class User extends CActiveRecord

{

	//define virtual variables.

	public $password2;

...



Then here is get function, which return user’s saved password




	public function getPassword2()

	{

		return $this->password2?$this->password2:$this->user_password;

	}






	public function rules()

	{

		// NOTE: you should only define rules for those attributes that

		// will receive user inputs.

		// arbitary array with scenario names

		//'on'=>array('update', 'create'),

		// string with scenario names separated with commas (spaces are ignored)

		//'except'=>'ignore, this, scenarios, at-all',

		//see http://www.yiiframework.com/wiki/56/reference-model-rules-validation

		//yii-conditional-validator is extension of Yii

		return array(


			//below is for virtual variables rules

			array('password2', 'safe'),

			array('password2', 'required','on'=>array('create')),

			array('password2', 'compare', 'compareAttribute'=>'user_password', 'operator'=>'==', 'compareType'=>'string'),

		);

	}




The above rule means in most case "password2" is safe attribute, only required on create new user, and if it post, then it will compare with user_password.

Hope it can help you a little bit.