Проверка запроса формы в Laravel: требуется в зависимости от метода (POST, PUT или DELETE)

#php #laravel #validation

#php #laravel #проверка

Вопрос:

Я использую запросы формы в Laravel для проверки. Я заметил постоянно возникающую закономерность, и я не смог найти для нее решение в SE (или, по крайней мере, поиск в Google мне не помог).

Допустим, мы создаем API и используем ApiResource от Laravel для создания обычных методов CRUD: store , update и delete

Очевидно, что когда мы сохраняем новую запись, поле id не является обязательным, но остальные поля могут потребоваться (и в большинстве случаев требуются). Но когда мы обновляем запись, мы сталкиваемся с противоположной ситуацией. id требуется, в то время как другие поля больше не требуются.

Возможно ли справиться с этой ситуацией с помощью одного запроса формы в Laravel? Можем ли мы использовать Laravel required_if разумным способом, чтобы избежать дублирования кода?

Редактировать: это не обязательно должно быть решение Laravel. Решение, использующее PHP, тоже подойдет (если оно чистое и соответствует принципам SOLID).

Комментарии:

1. Предоставляете ли вы поле id в качестве ввода формы, которым пользователь может манипулировать? Если id является первичным ключом, то не рекомендуется предоставлять поле id для манипулирования через форму. И если вы не предоставляете поле id через форму, то, я думаю, это даже не требует какой-либо проверки.

Ответ №1:

Я сталкивался с этой проблемой много раз, и я понимаю ваше разочарование…

С моей точки зрения и профессионального опыта, лучшим решением всегда было иметь конкретные FormRequest s для каждого случая:

  • Один для store со своими правилами
  • Другое для update с аналогичными правилами, но не такими, как store
  • И последнее для delete (наверняка намного меньше правил, чем у других, и без дублирования)

Я знаю, что вы сказали «нет дублирования кода», но, как сейчас, это невозможно (но у вас не должно быть дублирования кода, как я уже говорил ранее).

Вы сказали: «до тех пор, пока он чистый и соответствует принципам SOLID», помните SOLID, S = Единая ответственность, поэтому, если вы хотите решить эту проблему с помощью одного FormRequest , вы уже нарушаете S .Я не могу представить a FormRequest с 10 или 15 входами, и это зависит от того, является ли это store , update , или delete . Это не будет чистым и наверняка не будет соответствовать принципам SOLID.

Комментарии:

1. Что ж, я должен частично согласиться с вашим последним абзацем. Но я полагаю, что SOLID открыт для интерпретации, потому что определение того, что следует воспринимать как «ответственность», может отличаться от человека к человеку. Что касается меня, проверка входящих данных для модели — это одна из обязанностей, даже если она разбита на несколько подоснов. Я думаю, что смогу найти решение, поэтому я дам вам знать, если смогу его найти (если вы не возражаете).

2. @stressedout Пожалуйста, поделитесь со мной своим лучшим решением! Я бы с удовольствием взглянул на это! Но нет, SOLID не открыт для интерпретации, единая ответственность — это единая ответственность, например, если ваш код использует URL-адреса только в средствах массовой информации (Facebook, Twitter, Instagram и т. Д.), Ваша ответственность не будет заключаться в проверке того, какой носитель вы хотите, И у вас есть один файл и множество IFS, Вы должныесть 1 файл и шаблон, который делает его динамичным, но не легендарным 20 cases switch (надеюсь, вы следите за мной)

3. Что ж, спасибо. Я буду ждать ваших отзывов, когда найду решение. Но если я случайно написал ответ здесь, пожалуйста, также объясните мне, почему писать операторы if или case-switch — плохая идея, потому что я не вижу в них проблемы.

4. @stressedout неплохо иметь инструкции if или case-switch, но это может быть плохо, если лучший подход отличается, как я уже говорил ранее в качестве примера, если у вас есть код, который использует URL-адрес в средствах массовой информации, как новичок, вы наверняка будете использовать много if и switch , вы следует использовать шаблон Builder. Я не на 100% разбираюсь в шаблонах, это то, что мне нужно освоить, но важно понимать базовые шаблоны, такие как Builder, Mapper и другие.

5. @matiaslauriti Я согласен, что нам нужно учитывать принципы SOLID при разработке наших проектов. Я также согласен с вашим подходом к созданию конкретных файлов запросов там, где это необходимо. Для меня, например, использование UserPostRequest и UserPutRequest имеет больше смысла.

Ответ №2:

Как насчет проверки метода и последующего возврата набора правил на основе этого метода? Например, у меня есть InvoiceFormRequest со следующими правилами. Таким образом, я могу использовать один запрос формы для двух разных методов.

 /**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
    if ($this->isMethod('post')) {
        return [
           'template' => 'required',
           'due_by_date'   => 'required',
           'description'   => 'required',
           'charge_items'  => 'required',
        ];
    }

    if ($this->isMethod('put')) {
        return [
            'due_by_date'   => 'required',
            'description'   => 'required',
            'charge_items'  => 'required',
        ];
    }
}
 

Комментарии:

1. @stressedout это неплохое решение, но вы по-прежнему храните правила только в одном файле (нарушение идентификатора S ), но если вам нужно также использовать authorize , вы собираетесь сделать еще один if для этой части.

Ответ №3:

Вот два возможных решения, которые я придумал

  1. Используйте метод контроллера для возврата правильных правил проверки:
     public function rules()
    {
        $method = $this->route()->getActionMethod();

        switch($method){
            case 'store':
                return [
                    \ validation rules
                ]
            ...
        }
    }
 
  1. Вместо этого используйте $this->getMethod() вместо $this->route()->getActionMethod() и проверяйте с помощью методов HTTP.

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

Я думаю, это в значительной степени решает проблему дублирования кода.

Комментарии:

1. 1) Я уже отвечаю на это другому пользователю, но вы все еще нарушаете (SOLID) в некотором смысле. Теперь контроллер также должен знать, какие правила использовать, если это входит в FormRequest FormRequest обязанности. 2) Это тоже хороший подход. Я бы всегда придерживался дублирования FormRequests вместо того, чтобы иметь что-то не очень разборчивое.