7

假设我有一个可以有颜色的产品。根据产品类型,可能需要也可能不需要颜色字段。

如果总是需要颜色,我会在产品模型中包含以下内容

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

但是,我希望这取决于产品类型是动态的。

这应该在控制器中完成吗?我想在控制器中有如下内容:

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

解决这个问题的最佳方法是什么?

谢谢

4

5 回答 5

15

您可以使用场景。在模型中:

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

在控制器中:

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

因此,当模型的场景是时,将验证所需的颜色hasColour

于 2012-05-02T02:06:56.103 回答
11
class LoginForm extends CFormModel
{
    public $username;
    public $password;
}

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

现在 $form 有两个必填字段。

于 2013-03-12T09:13:25.480 回答
4

一种方法是使用自定义验证规则。例如,规则:

array('colour', 'requiredOnHasColour'),

然后是同一个模型类中的验证器方法:

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

更多信息:创建您自己的验证规则

于 2012-05-02T02:21:19.917 回答
1

如果您想做更复杂的逻辑,那么场景可能无法满足您的需求。然后您可以覆盖方法 init 并在那里执行所有定义验证规则的逻辑,将结果添加到 $validationRules 数组。而在 rules() 方法中,您只需返回该数组。像这样的东西:

 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;
    }
}
于 2014-04-26T10:25:35.560 回答
0

在您的 ActiveRecord 中,您可以在任何地方添加动态验证器。例如,我覆盖父方法 setAttributes 并添加 $this->validatorList->add() 取决于 $this->type 属性中的选定值。官方文档:https ://www.yiiframework.com/doc/api/1.1/CValidator

public function setAttributes($values, $safeOnly = true)
{
    $result = parent::setAttributes($values, $safeOnly);

    if (self::TYPE_PHONE == $this->type) {
        $this->validatorList->add(CValidator::createValidator('required', $this, ['phone', 'phonePrefix']));
    } elseif (self::TYPE_EMAIL == $this->type) {
        $this->validatorList->add(CValidator::createValidator('required', $this, ['email']));
    }

    return $result;
}
于 2020-01-20T12:28:41.877 回答