Model : Using Old Attribute In Rules


I find if there are a way to use actual attribute in rules.

More explanation:

I want to set a rules ONLY if the attribute are really updated. My idea is to do something like this (surely a lot of error):



  array('title', 'match', 'pattern' => $mypattern),


I know i can use scenario on controllers, but this model can be call on different controller, then find a way directly in models.



Why not just let the rules run every time?

Rules are expected to be static, that is you shouldn’t reference the current state of the model when creating them. That should be done in runtime, using inline validators for example.


Because old rules accept some charaters in title, new rules don’t accept this characters. If we set new rules on title, and user need to update something other than title : he can’t.


Found it:


if($oActualValue && $oActualValue->title==$this->title){

  return $oldRules;


  return $newRules;


Thanks :)

  1. In afterFind() store the "old" attributes you want to compare with.

  2. In the validation rules, use a custom function.

  3. In the custom function first check whether old != new, if so, create validator and execute it.

[edit: posted it at the same time you posted your solution]

[edit2:] so each time the framework calls your model’s rules() function you are hitting the database ?

You should use the default ActiveRecord ‘insert’ and ‘update’ scenarios. Use old rule in ‘update’ and new in ‘insert’ scenario.

Alternatively, force the user to update all non-validating fields when they update an old record, which is the approach I normally take. At least that way your records will move towards compliance with your new rules.

Yes, but sometimes, $oModel->title aren’t allowed to be updated.

I know it’s not the best solution, but we need to find a way where all user are happy :) (And we have a lot of user).


Oups, if someone want to see the system ,

Starting is here :

More fix after while …