mae
mae

Reputation: 15666

Yii2: Add/remove validation rules in Model from 3rd party module

In the main Yii2 application, how can we add validation rules to a Module (or an ActiveRecord) that comes with a 3rd party module?

Can we modify existing rules? Say we have the following rule:

['currency', 'in', 'range' => ['USD', 'GBP', 'EUR']],

How would we add or remove any currencies inside the 'range' array?

Keep in mind that we cannot simply extend the class and override rules() since that would not change the parent class that the module is using. If the above is impossible, please shed some light on a proper way to design a module to support validation rule customization in its models/activerecords.

EDIT 2021: Upon revisiting this question ... Just don't do this. It may seem like the right approach, but it's not. You will end up pulling your hair out when you are getting mysterious validation errors that you have no idea where they are coming from.

Upvotes: 0

Views: 1782

Answers (2)

Alexander Galitskiy
Alexander Galitskiy

Reputation: 1

you can create rules as key -> array in rules() method

$rules = [
['id', 'integer'],
'test' => ['name', 'string'], 
];

in child class unset rule by key

$parent = parent::rules();
unset($parent['test']);
return $parent;

Upvotes: 0

meysam
meysam

Reputation: 1794

I did same thing for my project. Actually I defined a getter on a model (That read some rules from db based on some information of user) and merge default rules with my new rules, it sounds like this:

public function getDynamicRules()
{
    $rules = [];

    if (1 > 2) { // Some rules like checking the region of your user in your case
        $rules[] = ['currency', 'min' => '25'];
    }

    return $rules;
}

public function rules()
{
    $oldRules = [
        ['currency', 'in', 'range' => ['USD', 'GBP', 'EUR']],
    ];

    return array_merge(
        $oldRules,
        $this->dynamicRules
    );
}

Also if your model is completely dynamic, easily you can extend your model from yii\base\DynamicModel. It has a lot of methods that can help you to implement a dynamic model. In terms of rules you can use DynamicModel::addRule method to define some new rules. From the documentation of DynamicModel:

/**
 * Adds a validation rule to this model.
 * You can also directly manipulate [[validators]] to add or remove validation rules.
 * This method provides a shortcut.
 * @param string|array $attributes the attribute(s) to be validated by the rule
 * @param mixed $validator the validator for the rule.This can be a built-in validator name,
 * a method name of the model class, an anonymous function, or a validator class name.
 * @param array $options the options (name-value pairs) to be applied to the validator
 * @return $this the model itself
 */

Upvotes: 0

Related Questions