Pull to refresh

Comments 7

А где, собсно, валидация вложенных атрибутов? Я ожидал чего-то в стиле:
public function rules() {
    return [
        [['field.child1.child2'], 'required'],
        [['anotherField.hisChild'], 'string', 'max' => 20],
    ];
}

Ну или чего-то в таком стиле. А тут виден только булев валидатор на поле result и использование валидаторов для загрузки значений по умолчанию, что немного вообще мимо кассы.
Так по обстоятельствам. В данном-то случае и нужно только автоприсвоение и ничего более, но кто ж мешает что-то ещё добавить? И, например, в форму вывести.
Я же показываю принцип, а не пишу пошаговое руководство.
Так не видно принципа ведь :)

Может стоит хотя бы поменять заголовок? Не хочу обидеть, но сюда просится «Использование модели для предварительной валидации данных для другой модели» и это довольно стандартный подход, когда, скажем, форма регистрации создаётся через отдельную модель, со своими полями и правилами, а не путём запихивания валидаторов и сценариев в модель пользователя.

Я же говорю:


Возможно, всё что я напишу ниже – очевидно, и все этим пользуются давно, но я вот недавно только это понял и придумал, так что, может, кому и пригодится.

Мне лично как-то неочевидно было до сих пор, к сожалению :)


И да, насчет заголовка – конечно, мы в данном случае используем \yii\base\Model для валидации (и присвоения значений) другой модели (что, в общем, в примерах есть), но и привязка к mongodb и её вложенным документам тоже важна, как по мне. Именно про это речь.

Я делал себе недавно такой валидатор: https://gist.github.com/paulzi/ad27c4689475ca442a2ea5880d659ff3

Использовать так:
public function rules() {
    return [
        ['params'], CompositeValidator::className(), 'rules' => [
            [['orderCallback'], 'match', 'pattern' => '|^https?://.+|'],
            [['orderCallback'], 'default', 'value' => null],
            [['calc', 'calcOasisPriceType'], 'filter', 'filter' => 'boolval'],
            [['factor'], 'filter', 'filter' => 'floatval'],
            [['calcOasisFactor'], 'default', 'value' => null],
            [['fields[].title'], 'required'],
        ]],
    ];
}


Если будет интересно, могу оформить в composer.

Правда есть тонкость, чтобы в Yii2 корректно показывалось в каком именно поле ошибка, нужно переопределить Html::getAttributeName(), а то там вырезается вложенность:
    public static function getAttributeName($attribute)
    {
        if (preg_match('/(^|.*\])([\w\.]+)(\[.*|$)/', $attribute, $matches)) {
            return $matches[2] . $matches[3];
        } else {
            throw new InvalidParamException('Attribute name must contain word characters only.');
        }
    }
Отличная задумка. Я сам уже пытался сделать нечто подобное, но мои попытки разбились о то, что придётся переписывать код из Model и Validator, что отвечает за создание и подключение валидатора. Тебя, судя по коду, это не смутило и ты заставил это работать :)

Оформи как Composer пакет, я постараюсь тоже сделать свой вклад.
На самом деле многое взял из стандартного EachValidator. Ок, будет время — сделаю)
Sign up to leave a comment.

Articles