Working on administrative section of a site I intensively used built-in CRangeValidator to check whether data provided by administrator lays within valid range of values. To be more precise, I check whether foreign keys' values being inserted into MySQL InnoDB table will not affect successful SQL query execution. It looks like this in rules() method of a model:
array( "init_node_id", "in", 'on' => array("edit"), 'range' => array_keys(Node::getNodeHierarchySelectOptions(array( 'projectId' => intval($this->id), 'updateCache' => true, 'slidesOnly' => true, 'full' => false ))), 'message' => Yii::t("admin", "Field must be in allowed values' range.") ),
Profiling database queries I just see that the behavior is not the one I wanted.
1. In `CModel` class all possible validators are created at once by createValidators() method even if they will not be used in current scenario. In my case Node::getNodeHierarchySelectOptions method to get a valid range deals with database executing not-cached queries to get relevant entries. This affects a performance but is acceptable price for rare administrative validations. Unfortunately, Node::getNodeHierarchySelectOptions will be invoked any time somebody uses the model for any another purpose (i.e. for searching).
2. I want SQL queries to get valid foreign keys and to insert new row in a table with save() method being executed within a single transaction so it would be perfect if each validation rule initialized just before calling it to validate an attribute but I can see that the current implementation with a single rules() method doesn't allow it.
I know that I can create a custom model method to validate an attribute but this way CRangeValidator (and maybe some other validators) remains useful only for simple cases when properties used to initialize a validator are predefined and can't be changed in time.
That's why I start this to topic to discuss a possibility to introduce some changes in further Yii releases that will help to improve built-in validators and allow them to be used in cases described above.