Использование сервиса в форме в валидации

Обсуждаем, как правильно строить приложения
Ответить
Аватара пользователя
SiZE
Сообщения: 2817
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Использование сервиса в форме в валидации

Сообщение SiZE »

Например, надо создать статус и проверить есть ли уже существующий статус в базе. От валидации Й я отказываться не хочу. Уместно ли обращаться из модели формы (\yii\base\Model) к модели (\yii\db\ActiveRecord) напрямую при наличии сервиса, работающего с этой моделью?

Стуктура такая:

/app/services/StatusService.php

Код: Выделить всё

namespace app\services;

class StatusService
{
    // базовые операции findById(), updateFromForm() и тд
}
 
/app/models/Status.php

Код: Выделить всё

namespace app\models;

class Status extends \yii\db\ActiveRecord
{
    // Модель сгенерированная gii
}
 
/app/forms/StatusForm.php

Код: Выделить всё

namespace app\forms;

class StatusForm extends \yii\base\Model
{
    public $id;
    public $name;
    public $alias;
    
    public function __construct($id = null, $config = array())
    {
        $this->id = $id;
        parent::__construct($config);
    }
    
    public function rules()
    {
         return [
            [['name', 'alias'], 'required'],
            [['name', 'alias'], 'string', 'max' => 32],
            // Можно ли тут задействовать сервис?
            ['alias', 'unique', 'targetClass' => 'app\models\Status', 'filter' => function (Query $query) {
                $query->andFilterCompare('id', $this->id, '<>');
            }],
         ];
    }
}
 
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Использование сервиса в форме в валидации

Сообщение ElisDN »

Как раз SignupForm проверяет на уникальность в viewtopic.php?f=34&t=36725&p=188218#p188218
Аватара пользователя
xoma
Сообщения: 641
Зарегистрирован: 2009.04.02, 15:24
Откуда: Ногинск
Контактная информация:

Re: Использование сервиса в форме в валидации

Сообщение xoma »

findById и прочие find* это не service, это скорее repository
Аватара пользователя
SiZE
Сообщения: 2817
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: Использование сервиса в форме в валидации

Сообщение SiZE »

ElisDN писал(а):Как раз SignupForm проверяет на уникальность в viewtopic.php?f=34&t=36725&p=188218#p188218
Т.е. стандартные unique и exist без переделки не получится использовать, я правильно понял?
Аватара пользователя
SiZE
Сообщения: 2817
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: Использование сервиса в форме в валидации

Сообщение SiZE »

xoma писал(а):findById и прочие find* это не service, это скорее repository
Да, но у меня пока только сервис =)
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Использование сервиса в форме в валидации

Сообщение ElisDN »

SiZE писал(а):Т.е. стандартные unique и exist без переделки не получится использовать, я правильно понял?
Стандартные используют AR. Если у Вас нет AR, то не получится.
Последний раз редактировалось ElisDN 2016.08.12, 13:07, всего редактировалось 1 раз.
Аватара пользователя
xoma
Сообщения: 641
Зарегистрирован: 2009.04.02, 15:24
Откуда: Ногинск
Контактная информация:

Re: Использование сервиса в форме в валидации

Сообщение xoma »

SiZE писал(а):
ElisDN писал(а):Как раз SignupForm проверяет на уникальность в viewtopic.php?f=34&t=36725&p=188218#p188218
Т.е. стандартные unique и exist без переделки не получится использовать, я правильно понял?

Имхо используйте, нет ничего плохо в AR, если использовать умеренно и не пичкать модельки всем подряд.
Если уж совсем хотите все правильно делать - берите Doctrine.
Аватара пользователя
SiZE
Сообщения: 2817
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: Использование сервиса в форме в валидации

Сообщение SiZE »

Если в паттерн MVC мы внедряем сервисный слой. Значит ли это что мы нигде не используем модель AR кроме самой AR и сервиса? И все обращения к ней должны завязываться на сервис? Или все же допускается, как в моем примере использование в формах для проверок?
Аватара пользователя
samdark
Администратор
Сообщения: 9489
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Использование сервиса в форме в валидации

Сообщение samdark »

В идеале это означает полную изоляцию того, за что отвечает вводимый сервисный слой.
Аватара пользователя
xoma
Сообщения: 641
Зарегистрирован: 2009.04.02, 15:24
Откуда: Ногинск
Контактная информация:

Re: Использование сервиса в форме в валидации

Сообщение xoma »

xoma писал(а):
SiZE писал(а):
ElisDN писал(а):Как раз SignupForm проверяет на уникальность в viewtopic.php?f=34&t=36725&p=188218#p188218
Т.е. стандартные unique и exist без переделки не получится использовать, я правильно понял?

Имхо используйте, нет ничего плохо в AR, если использовать умеренно и не пичкать модельки всем подряд.
Если уж совсем хотите все правильно делать - берите Doctrine.
Начните с простого, не стоит сразу бросаться применять все подходы DDD и прочего.

Выпилите логику из контроллеров - поместите ее в сервисы (Component).
Выпилите из модели все кастомные find* методы - поместите их в репозитории (пойдут repository с AR внутри).
Оставьте AR-модели в проекте, но используйте их для простых вещей (CRUD)
Выпилите из моделей и сервисов обращение к Yii::$app - это табу.
Не используйте модели как формы.Для всех форм делайте именно форму именно с теми полями, которые нужны и потом мапте их на модель.

Выполнив хотябы вот эти 5 пунктов Вы заметите разницу.
А уже потом настанет момент просветленя и можно будет добавить еще 5-6 таких пунктов.
Не переусложняйте все лишними слоями пока не прочувствовали это на практике - толку не будет.
Не следуйте слепо всем мантрам, которые есть в умных статьях и книгах.

Вот так -)
Аватара пользователя
SiZE
Сообщения: 2817
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: Использование сервиса в форме в валидации

Сообщение SiZE »

Понятно. Спасибо.
Аватара пользователя
samdark
Администратор
Сообщения: 9489
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Использование сервиса в форме в валидации

Сообщение samdark »

Не используйте модели как формы.Для всех форм делайте именно форму именно с теми полями, которые нужны и потом мапте их на модель.
Имелось ввиду не использовать модели AR в качестве форм, а не модели вообще.
Аватара пользователя
xoma
Сообщения: 641
Зарегистрирован: 2009.04.02, 15:24
Откуда: Ногинск
Контактная информация:

Re: Использование сервиса в форме в валидации

Сообщение xoma »

Sam Dark писал(а):
Не используйте модели как формы.Для всех форм делайте именно форму именно с теми полями, которые нужны и потом мапте их на модель.
Имелось ввиду не использовать модели AR в качестве форм, а не модели вообще.
Ага +)
Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

Re: Использование сервиса в форме в валидации

Сообщение slavcodev »

Вынос ограничений сущности из сущности нарушение инкапсуляции.
Если вы думаете, просто введя конвенцию в команде,
что устанавливать надо в сущность только валидные данные проверенные до этого,
и получите не убиваемый код, то вы сильно ошибаетесь.

А еще больше ошибается ваш работодатель.
После вас прийдет другой программист, не знающий этой конвенции, и прощай приложение, прощай бизнес.
Жду Yii 3!
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Использование сервиса в форме в валидации

Сообщение ElisDN »

slavcodev писал(а):Вынос ограничений сущности из сущности нарушение инкапсуляции.
Если вы думаете, просто введя конвенцию в команде,
что устанавливать надо в сущность только валидные данные проверенные до этого,
и получите не убиваемый код, то вы сильно ошибаетесь.
Кстати да, клиентская валидация в формах может дублировать, но никак не заменяет валидацию внутри ядра. Клиентскую можно и не производить, если не нужно сразу поля по Ajax подсвечивать.
Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

Re: Использование сервиса в форме в валидации

Сообщение slavcodev »

ElisDN писал(а):Кстати да, клиентская валидация в формах может дублировать, но никак не заменяет валидацию внутри ядра. Клиентскую можно и не производить, если не нужно сразу поля по Ajax подсвечивать.
Поосторожнее с дублями правил, их несогласованность может привести клиента в ступор :D
Жду Yii 3!
sda
Сообщения: 334
Зарегистрирован: 2013.12.19, 09:29

Re: Использование сервиса в форме в валидации

Сообщение sda »

ElisDN писал(а):
slavcodev писал(а):Вынос ограничений сущности из сущности нарушение инкапсуляции.
Если вы думаете, просто введя конвенцию в команде,
что устанавливать надо в сущность только валидные данные проверенные до этого,
и получите не убиваемый код, то вы сильно ошибаетесь.
Кстати да, клиентская валидация в формах может дублировать, но никак не заменяет валидацию внутри ядра. Клиентскую можно и не производить, если не нужно сразу поля по Ajax подсвечивать.
Под клиентской валидацией вы имеете ввиду ту, что вызывается до того, как данные попадут в сервис (\yii\base\Model), а под валидацией внутри ядра, ту что непосредственно будет вызвана перед сохранением данных в хранилище. Верно?
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Использование сервиса в форме в валидации

Сообщение zelenin »

sda писал(а):
ElisDN писал(а):
slavcodev писал(а):Вынос ограничений сущности из сущности нарушение инкапсуляции.
Если вы думаете, просто введя конвенцию в команде,
что устанавливать надо в сущность только валидные данные проверенные до этого,
и получите не убиваемый код, то вы сильно ошибаетесь.
Кстати да, клиентская валидация в формах может дублировать, но никак не заменяет валидацию внутри ядра. Клиентскую можно и не производить, если не нужно сразу поля по Ajax подсвечивать.
Под клиентской валидацией вы имеете ввиду ту, что вызывается до того, как данные попадут в сервис (\yii\base\Model), а под валидацией внутри ядра, ту что непосредственно будет вызвана перед сохранением данных в хранилище. Верно?
клиентская - это то, что видите в браузере.
sda
Сообщения: 334
Зарегистрирован: 2013.12.19, 09:29

Re: Использование сервиса в форме в валидации

Сообщение sda »

Я понял так, что речь о валидации на стороне сервера. Та что в \yii\base\Model уйдет в виде ошибок в браузер (её назвали клиентской), но говорят, что нужно еще продублировать валидацию непосредственно перед сохранением данных в хранилище, чтобы консистентность данных не нарушилась, если вдруг кто накосячит с правилами валидаций в \yii\base\Model. Я так это понял. Прошу прояснить.
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Использование сервиса в форме в валидации

Сообщение zelenin »

sda писал(а):Я понял так, что речь о валидации на стороне сервера. Та что в \yii\base\Model уйдет в виде ошибок в браузер (её назвали клиентской), но говорят, что нужно еще продублировать валидацию непосредственно перед сохранением данных в хранилище, чтобы консистентность данных не нарушилась, если вдруг кто накосячит с правилами валидаций в \yii\base\Model. Я так это понял. Прошу прояснить.
я понял как вы поняли из предыдущего вашего комментария. И следующим комментарием я расставил точки над i. Еще раз прояснить?
Ответить