Validation scenarios

February 16th, 2009

As of Yii 1.0.2 you may now define validation scenarios. This is very useful if for instance you have multiple places in your application that you validate a model, but in each instance you may want different validation rules. For instance, perhaps in your user registration form you want to have the “username”, “email” and “password” fields to be required, while on your “user recovery” page, you only want the “email” field to be required. You may see a problem here. If you set all the fields to be required, then your user recovery page won’t work, as it does not allow a user to supply neither a password nor a username.

The perfect solution to this are validation scenarios. You can attach a validation scenario to a validation rule through the ‘on’ property. You may already know you can set the ‘on’ property to either ‘insert’ or ‘update’, which will automatically cause the rule to only be used on the corresponding type of save. However sometimes these two options are not enough. So now with this new enhancement, you may set it to any value you want. Let me show an example:

<?php
//in user model
public function rules() {
	return array(
		//Set required fields
 		//Applies to 'register' scenario
 		//Note 'on' property
		array('username, password, password_repeat, email', 'required', 'on' => 'register'),
 
		//Applies to 'recover' scenario
		array('email', 'required', 'on' => 'recover'),
 
		//Applies to all scenarios
		array('username, password', 'length', 'max'=>35, 'min'=>3),
 
		//This rule checks if the username is unique in the database in
		//the 'register' scenario (we don't want it to check for uniqueness
		//on the login page for instance)
		array('username', 'unique', 'on' => 'register'),
 
		//This rule applies to 'register' and 'update' scenarios
		//Compares 'password' field to 'password_repeat' to make sure they are the same
		array('password', 'compare', 'on' => 'register, update'),
	);
}

With this setup Yii will be able to tell which fields are required in which scenarios. As a bonus I threw some other rules for example. Reading the comments will give you an understanding of that. You may also note from the ‘compare’ rule that you may define a rule to be used on multiple scenarios by separating them with commas.

Now when you wish to run validation under a specific scenario you must define it in when calling CModel::validate(), as so

<?php
$user->validate('<scenarioName>'); //runs validation under the given scenario
 
//example:
if ($user->validate('register')) {
	$user->save(false);
}

So the above example will validate the user under the ‘register’ scenario.

Leave a comment if I have left any unanswered questions on this enhancement

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Technorati
  • Reddit
  • RSS
  • Twitter

Categories: Yii

Tags: Leave a comment

Comments Feed16 Comments

  1. Safe attribute scenarios | Jonah’s Thoughts

    […] you read my last article on validation scenarios then you may understand why in different scenarios you may need different attributes to be […]

  2. Qiang

    Excellent article! You have well explained scenario-based validation.

  3. Safe attributes tip | Jonah’s Thoughts

    […] my last two posts [1, 2] I explained how to define scenario-based validation rules and safe attributes. Something I have […]

  4. hehe

    imvho you did a mistake:

    is:
    array(‘password’, ‘compare’, ‘on’ => ‘register, update’),

    should be:
    array(‘password’, ‘compare’, ‘compareAttribute’=>’password_repeat’, ‘on’=>’register, update’),

    cheers,
    michael

  5. Jonah

    michael,

    Actually, Yii will automatically assume that the compareAttribute is the same name as the source attribute but with a ‘_repeat’ suffix, if it is not defined explicitly.

    http://www.yiiframework.com/doc/api/CCompareValidator

  6. hehe

    good to know ;)

  7. Brandon P

    Why not have something like this where you can set the current scenario of a model to help with validation AND safeAttributes

    $user->setScenario(”);
    $user->save();

  8. Jonah

    I introduced that idea to the developer but at the time he did not like the idea.. I do not totally remember why

  9. Jonah

    As of today, you may in fact use

    $user->setScenario();

    It has just been implanted but about 9 hours ago.

    The old way has even been “depreciated”

  10. ryan

    Good to know!
    It’s fun to work with yii and read your articles.

  11. chris

    Thx your article helped me ;)

  12. Larry Ullman's Blog » Validation Scenarios in Yii

    […] long, long time ago, in a land far, far away (as far as I know), Jonah Turnquist wrote an article on validation scenarios in Yii. It’s a topic that I hadn’t paid too much attention to until playing around with the […]

  13. Rew

    Thanks for the post, but I had trouble getting it to work with your code… not sure if things have changed in the latest version of Yii.

    $model = new User(‘register’); worked for me instead.

  14. otávio sampaio

    Hey Jonah,

    How awesome this kind of scenario. It shakes a little the use of polymorphism.

    BTW, I came to your blog just because you’ve said at yii’s forum that you hate the way the view libs behave. And I trully agree with you. I just came from Rails and now I run a team focused on php development and, despite the quality of the rest of yii framework, they truly made some awkward choices like:

    – The way they implement active record
    – the way they implement views (that dump so much code at a simple page and is sooooooo not reusable).

    Write more! You’ve got some really useful thoughts.

    best regards from Brazil….

    Otávio

  15. Larry Ullman

    I’m not sure if you’re aware of this or not, or if you even care, but it was brought to my attention tonight that a Blogspot site had one of my blog postings up verbatim. While looking for any others, I suspected, and concluded, that ALL the posts there are taken from elsewhere. I found your posting:
    http://php-thoughts.cubedwater.com/2009/validation-scenarios/
    Here:
    http://haythamhosney.blogspot.com/2011/11/yii-validation-scenarios.html

    At the top of the page, Google provides a way to report abuse (including copyright infringement), if you’re so inclined.

    Larry

  16. Babak Bandpey

    You can also use this syntax.
    public function rules(){
    $rules = [
    .
    .
    .
    .

    ];

    if($some_true_condition) {
    $rules = array_merge($rules, [[‘field_name’, ‘required’]]);
    }
    return $rules;
    }

Leave a comment


seven + 6 =

Feed

http://php-thoughts.cubedwater.com / Validation scenarios