Yii – динамическое изменение правил с контроллера

Допустим, у меня есть продукт, который может иметь цвет. В зависимости от типа продукта поле цвета может потребоваться или не потребоваться.

Если цвет всегда необходим, в модели продукта у меня будет следующее:

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 } } 

Каков наилучший способ приблизиться к этому?

благодаря

Вы можете использовать сценарий. В модели:

 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

 class LoginForm extends CFormModel { public $username; public $password; } $form = new LoginForm(); $form->validatorList->add( CValidator::createValidator('required', $form, 'username, password') ); 

Теперь $ form имеет два обязательных поля.

Один из подходов заключается в использовании специального правила валидации. Например, правило:

 array('colour', 'requiredOnHasColour'), 

А затем метод валидатора в том же классе модели:

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

Дополнительная информация: Создайте собственное правило проверки

Если вы хотите сделать более сложную логику, сценарии могут не удовлетворить ваши потребности. Затем вы можете переопределить метод 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; } }