Yii2 - проверка вложенных объектов - PullRequest
0 голосов
/ 06 июня 2018

Вот вопрос по теме, о которой я долго думал.

В Yii2 рекомендуется обычно создавать модели форм для ваших запросов.Правила добавляются в эти модели для проверки ввода.Примером является EntryForm в руководстве по Yii2

<?php

namespace app\models;

use Yii;
use yii\base\Model;

class EntryForm extends Model
{
    public $name;
    public $email;

    public function rules()
    {
        return [
            [['name', 'email'], 'required'],
            ['email', 'email'],
        ];
    }
}

Моя проблема в том, что у нас есть вложенные объекты.Примером является форма для создания Customer с несколькими Branches .Если Customer и Branch являются двумя отдельными моделями, но обе отправляются в одной форме, что является лучшим вариантом для проверки входных данных из такой вложенной формы.Имейте в виду, что здесь вход является вложенным.Пример:

{
  "name": "customer",
  "vat_no": "12345678",
  "time_zone": 277,
  "category": 1,
  "email": "customer@mycustomer.com",
  "stores":[
    {
        "name": "store1",
        "phone": 1234567
    },
    {
        "name": "store2",
        "phone": 2345678
    }
]
}

1 Ответ

0 голосов
/ 06 июня 2018

Для простых случаев вы можете использовать одну модель и пользовательский валидатор внутри вашей модели формы:

public function rules() {
    return [
        // ...
        ['stores', 'validateStores'],
    ];
}

public function validateStores() {
    $phoneValidator = new StringValidator(); // use real validators
    $nameValidator = new StringValidator(); // use real validators
    foreach ($this->stores as $store) {
        if (!$phoneValidator->validate($store['phone'], $error)) {
            $this->addError('stores', $error);
            return; // stop on first error
        }
        if (!$nameValidator->validate($store['name'], $error)) {
            $this->addError('stores', $error);
            return; // end on first error
        }
    }
}

validateStores() может быть извлечено для разделения класса валидатора, тогда вы также можете использовать EachValidator вместо foreach.


Для более сложных вложенных моделей вам, вероятно, следует создать отдельную модель StoreForm для магазинов (таким образом, у вас будут вложенные модели форм) и вызвать validate()на детей.

/**
 * @var StoreForm[]
 */
public $stores;

public function rules() {
    return [
        // ...
        ['stores', 'validateStores'],
    ];
}

public function validateStores() {
    foreach ($this->stores as $store) {
        if (!$store->validate()) {
            $this->addError('stores', 'Stores config is incorrect.');
            return;
        }
    }
}
...