Yii - dynamically change rules from controller

2019-03-20 03:28发布

Let's say I have a product which can have a colour. Depending on the product type, the colour field may or may not be required.

If colour is always required, I would have the following in the product model

public function rules()
{
    return array(
        array('colour', 'required')
    );
}

However, I want this to be dynamic depending on the product type.

Should this be done in the controller? I would imagine having something like the following in the controller:

public function actionOrder() {
    // ....
    if ($product->HasColour) {
        // set the colour validation to be required
    } else {
        // set the colour validation to be not required
    }
}

What is the best way to approach this?

Thanks

标签: php yii
4条回答
家丑人穷心不美
2楼-- · 2019-03-20 04:00
class LoginForm extends CFormModel
{
    public $username;
    public $password;
}

$form = new LoginForm();
$form->validatorList->add(
    CValidator::createValidator('required', $form, 'username, password')
);

Now $form has two required fields.

查看更多
兄弟一词,经得起流年.
3楼-- · 2019-03-20 04:09

You can use scenario. In the model:

class Model extends CActiveRecord {
    // ....
    public function rules() {
        return array(
            array('colour', 'required', 'on' => 'hasColour')
        );
    }
    // ....
}

And in the controller:

public function actionOrder() {
    // ....
    $model = new Product();
    if ($product->HasColour) {
        $model->setScenario('hasColour');
    }
}

So, required colour will be validated when the model's scenario is hasColour

查看更多
狗以群分
4楼-- · 2019-03-20 04:13

One approach is to use a custom validation rule. For example, the rule:

array('colour', 'requiredOnHasColour'),

And then the validator method in the same model class:

public function requiredOnHasColour($attribute, $params) {
    if ($this->hasColour && $this->$attribute == null)
        $this->addError($attribute, 'Colour is required.');
}

More info: Create your own validation rule

查看更多
姐就是有狂的资本
5楼-- · 2019-03-20 04:16

If you want to do more complicated logic, then scenarios might not satisfy your needs. Then you can override method init and do all the logic that define validation rules over there, adding results to $validationRules array. And the in rules() method you just return that array. Something like that:

 class Person extends CActiveRecord
{
    public function init(){
        if( TRUE){
            $this->validationRules[] = array('first_name','required');
            $this->validationRules[] = array('last_name','required');
        }

    }

    public $validationRules = array(
        array('email', 'required'),
        array('email, email1, email2, email3', 'email', 'message'=>'Email format is invalid'),
        array('email, address, email1, email2, email3', 'length', 'max'=>255),

    );

    public function rules()
    {
        return $this->validationRules;
    }
}
查看更多
登录 后发表回答