Safe attributes doesn't work

Hello,

I am having a problem and I don’t know how to solve it.

In my model, I want to declare most attributes as unsafe by default, and make them safe only for some specific scenario.

Here is what I did in my model’s rules :




array('xp, level, cash', 'numerical', 'integerOnly'=>true),


// Unsafe Attributes

array('level, cash', 'unsafe'),


// Safe Attributes

array('level, cash', 'safe', 'on'=>'adminUpdate'),



But when I try to do massive assignment, the attributes declared as unsafe, it doesn’t work even if the scenario is adminUpdate. And if I remove them from the unsafe line, massive assignment works.

In the controller, I set the scenario like this :

$model->scenario = ‘adminUpdate’;

I checked the post data, and it is correct.

Thanks

Try swapping the order of the safe/unsafe rules.

(untested)

/Tommy

I just tried to reverse the order, and it still doesn’t work !

you can use CUnsafeValidator…

I don’t understand, isn’t it what I am already doing ?

You can create a custom validator e.g conditionalSafe(). There’s a safe attribute in the CValidator (base) class. Default value is true, you should set it to false except for the scenario(s) specified, adminUpdate in your case. Of course you can instead add an explicit list of complementary scenarios to the unsafe rule.

(untested)

/Tommy

Try this:

[PHP]

array(‘xp’, ‘numerical’, ‘integerOnly’=>true),

array(‘level, cash’, ‘numerical’, ‘integerOnly’=>true, ‘on’=>‘adminUpdate’),

[/PHP]

I believe that your first rule make ‘level’ and ‘cash’ attributes save for all scenarios since you define them as ‘numerical’.

Thats at least how I understood the rule system.

I guess this will be a good solution for the question asked. I just want to mention this will not enforce the specified validation in the (unprobable) case that level/cash is assigned one by one.

/Tommy

I did this, I defined my rules with the ‘on’ property if the attributes is not safe for every scenario.

I would have prefered defining the rules for every property, then defining a list a unsafe attributes, and make them safe only for certain scenario.

But at least, it works this way, so I am going to do like this.

Thank you very much :)

If i understand right, you want to separate validation rules and definition of safe attributes. I also found this very useful if you have a model with many attributes and many scenarios. The easiest way to do get this, is to override getSafeAttributeNames(). Then rules() will no longer be checked for safe attributes. All your attributes will be unsafe by default and you can define the safe attributes per scenario much cleaner:





public function getSafeAttributeNames()

{

    if ($this->scenario='register')

        return array('lastname','firstname');

    if ($this->scenario='login')

        return array('username','password');

    //...

}



All attributes are unsafe by default. Only when they appear in a validation they’re marked as safe, and you should make those validators scenario-specific.

I think he wants to do something similar like i tried here:

http://www.yiiframework.com/forum/index.php?/topic/12287-unexpected-behavior-of-cvalidatorsafe

This exactly what I wanted to do ! (except that some attributes should be safe all the time (but that could be easily done in getSafeAttributesNames()). I think I am going to use this method, I like it :)

Thank you very much !