#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:
Вот два возможных решения, которые я придумал
- Используйте метод контроллера для возврата правильных правил проверки:
public function rules()
{
$method = $this->route()->getActionMethod();
switch($method){
case 'store':
return [
\ validation rules
]
...
}
}
- Вместо этого используйте
$this->getMethod()
вместо$this->route()->getActionMethod()
и проверяйте с помощью методов HTTP.
Вы также можете сохранить свои правила проверки в массиве и манипулировать им, чтобы уменьшить дублирование кода.
Я думаю, это в значительной степени решает проблему дублирования кода.
Комментарии:
1. 1) Я уже отвечаю на это другому пользователю, но вы все еще нарушаете (SOLID) в некотором смысле. Теперь контроллер также должен знать, какие правила использовать, если это входит в
FormRequest
FormRequest
обязанности. 2) Это тоже хороший подход. Я бы всегда придерживался дублированияFormRequests
вместо того, чтобы иметь что-то не очень разборчивое.