Лучший способ отделить данные проверки - PullRequest
1 голос
/ 12 июня 2019

У меня действительно нет проблем со своим кодом, больше похоже на проблему с тем, как структурирован мой код.

Мой проект написан на Laravel, и я использую контроллеры ресурсов, которые laravel генерирует для нас. Внутри функции Update () я много работаю с данными.

Некоторые примеры:

Update ()

public function update(Request $request)
{

    $post = (object) $request->all();

    unset($post->XDEBUG_SESSION_START);

    $this->preparePassword($post);

    $this->prepareMail($post);

    $this->prepareAvailability($post);

    $this->prepareZip($post);

    $this->prepareSofttags($post);

    $user = User::find(Auth::id());

    $user->update((array) $post);
}

Обновление вызывает функции для обработки данных. Некоторые примеры:

private function prepareAvailability(stdClass &$data) : void
{
    // If no days or a date is selected, return
    if (empty($data->available_days) && empty($data->available_from)) {
        return;
    }

    // when days are given (available)
    if ($data->available_days) {
        $days = (int) $data->available_days;
        $avail_level = 0.2 * $days;

        $data->avail_level = $avail_level;
        $data->avail_from = mysqldate(strtotime('today'), true);

        unset($data->available_days);
    }

    // When a date is given (no available)
    if ($data->available_from) {
        $data->avail_level = 0;
        $data->avail_from = mysqldate(strtotime($data->available_from), true);

        unset($data->available_from);
    }
}

и:

private function prepareZip(stdClass &$data) : void
{
    if (empty($data->zip)) {
        return;
    }

    $zip4d = (int) substr($data->zip, 0, 4);
    $zipData = Zip::check($zip4d);
    $data->city = $zipData->name;
}

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

Есть ли лучший способ, я думал о чертах, но черты должны быть совместимы с каждым классом. Не относится к одному контроллеру.

Есть какие-нибудь мысли по этому поводу?

P.S. Я использую некоторые вспомогательные функции, если вы не понимаете некоторые функции, которые используются в коде, такие как «mysqldate»

Ответы [ 2 ]

1 голос
/ 12 июня 2019

Из того, что я вижу, у вашего контроллера много обязанностей, что обычно означает, что сейчас самое время разделить вещи. Я думаю, что следующее может быть извлечено в другие классы:

  1. Проверка ввода (проверка наличия данных). Например, available_days является обязательным полем. Для этого проверка запроса формы laravel может быть использована.
  2. Проверка данных (проверка правильности данных). Например, почтовый индекс должен быть разбит на цифры и буквы. Для этого вы можете ввести объекты-значения для почтового индекса, например, пример
  3. Проверка домена (содержит правила для вашего проблемного домена) Например, если дата available_from не указана, available_from будет сегодня). Обычно это классы, которые гарантируют, что они не могут быть в недопустимом состоянии (то есть после создания они всегда полны, и данные имеют смысл). Они делают это, применяя правила домена в конструкторе и других методах, которые изменяют содержащиеся в них данные.

В качестве бонуса, если разделить ответственность таким образом, это обычно означает, что (юнит) тестирование станет легче.

Если вы хотите больше об этом, дайте мне знать. А пока я быстро написал.

0 голосов
/ 13 июня 2019

Получив совет, я начал работать с классом / методом / концепцией Laravel FormRequest

https://laravel.com/docs/5.8/validation#form-request-validation

Я очистил свой код, и теперь моя функция обновления теперь «одна строка»', как вы могли видеть, это был беспорядок раньше.Результат:

public function update(UpdateUserRequest $request)
{
    user()->update($request->all());
    // user() helper function short for Auth::user()
}

Маленькое объяснение.Мой $ request - это не класс Request, а класс UpdateUserRequest:

update(UpdateUserRequest $request)

'php artisan make:request UpdateUserRequest'

Этот класс имеет функцию с именем

public function withValidator($validator)

Эта функция вызывается при выполнении запроса, поэтому перед нимвходит в логику контроллера, в этом классе я проверяю данные и переназначаю значения $ request, как я делал раньше.

Конечный результат:

public function withValidator()
{
    $post = (object) $this->all();
    // Update password if possible
    $this->preparePassword($post);
    // Update mail
    $this->prepareMail($post);
    // Update availability
    $this->prepareAvailability($post);
    //
    $this->prepareZip($post);
    //
    $this->prepareSofttags($post);

    $this->merge((array) $post);
}

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

Я собираюсь изменить немного больше в этой базе кода, потому что сейчас я вставляю все данные запроса в каждую приватную функцию,но лучше просто вставить данные, которые я хочу проверить, и изменить $ request (в данном случае $ this) сразу после проверки.Так что, в конце концов, у меня нет слияния.

PS Мой английский не очень хорош, поэтому, если у меня есть какие-то опечатки или я не совсем понимаю, о чем говорю, пожалуйста, спросите меня об этом.

PSS Если вы видите что-нибудь, что я могу улучшить, не сдерживайтесь и скажите мне:)

Спасибо всем за совет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...