Setter/getter And Validation

Hello world,

I’ve massive problems using setters and getters together with validation

There is no problem introducing a virtual attribute to access expensive functions:


public function getmyAttribute() {

  return(...read from file...);

}

public function setmyAttribute($theValue) {

  ...write to file...($theValue);

}



When opening a form, the value will be read from the file and filled into the form. When saving the form, the new value will be written into the file - perfect!

But at the moment I want to validate the value within the form before saving, the trouble starts. I like this Ajax validation, but when using an virtual attribute, the following happens:

  1. entering a new value inside the input element of the form and press TAB

  2. setmyAttribute() is called and the new value is saved into the file (notice: this is done even without clicking submit)

  3. getmyAttribut() is called to readout the value from the file. The validation is done based on this read value - which could be different from that one in the form.

How can I prevent calling setmyAttribute during (Ajax) validation of a form?

Thanks

Achim

you can set a value to a private attribute in setmyAttribute method and do the file writing in afterValidate method:




private _myAttribute;


public function setmyAttribute($theValue) {

  $this->_myAttribute=$theValue;

}


protected function afterValidate()

{

    //...write to file...($this->_myAttribute)

      

    return parent::afterValidate();

}



Hmm, generally a good idea, but why do you propose afterValidate(), I don’t want to save during validation!

But if your proposed code is inserted in afterSave() it works fine, I’ve just tried. Now it looks like:


public function getMyAttribute() {

	if(isset($this->cachedMyAttribute))

		return($this->cachedMyAttribute);

	else

		return(...read from file...);

}


public function setMyAttribute($theValue) {

		$this->cachedMyAttribute = $theValue;

}


public function afterSave()  {

	...write to file...($this->cachedMyAttribute);


	return parent::afterSave();

}



The only drawback I see is that it looks a little scattered. The real saving functionality is not in setmyAttribute() anymore, they all (because I’ve more than one virtual attributes within this model) are bundles within the afterSave(). This will reduce maintainability a bit…

Furthermore this all looks like it is a workaround for a misunderstood concept. I can’t image that there is no simpler solution build in Yii.

Nevertheless, thanks for the hint

Achim

it was just an example

as your attribute is a virtual attribute ,assigning a value to it calls the set method, so you can’t put the saving logic on it, it’s the same process that CActiveRecord do with database columns