Yii2 - Проверка вложенных объектов

54
4

Вот вопрос о теме, о которой я размышлял некоторое время.

В 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'],
];
}
}

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

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

спросил(а) 2018-06-06T16:41:00+03:00 1 год, 6 месяцев назад
1
Решение
47

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

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() может быть извлечен для разделения класса 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;
}
}
}

ответил(а) 2018-06-06T17:54:00+03:00 1 год, 6 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема