@lexstile

Как правильно выстраивать архитектуру метода контроллера на laravel?

У есть метод на удаление проекта:
public function destroy($id)
    {
        $code = 400;
        $message = Response::getErrorMessage('Не удалось удалить проект');
        
        if (!ProjectPolicy::requestDelete($id)) {
            $code = 403;
            $message = Response::getErrorMessage('Ошибка доступа');
        }

        $project = Project::find($id) ?: [];

        if ($project) {
            $project->delete();
            $this->deleteImageProject($project->logo);
            $code = 200;
            $message = Response::getSuccessMessage('Вы успешно удалили проект');
        }
        
        return response()->json($message)->setStatusCode($code);
    }

Как грамотно и правильно выстраивать архитектуру метода? (проверки, коды ответа и т. п.)
Как ни крутил - получается уныло совсем.
  • Вопрос задан
  • 278 просмотров
Решения вопроса 3
@jazzus
Не нужно ничего крутить. См Policy, Model Binding и Localization в документации Ларавел.
Ответ написан
Комментировать
iMedved2009
@iMedved2009
Не люблю людей
1.public function destroy($id)
Используйте model binding - удобно же.

2. ProjectPolicy::requestDelete($id)
есть прекрасный вариант расставлять policy на уровне роутера - can:
Route::delete('/project/{project}', [Controller::class, 'method'])->can('delete', 'project');


3. $project = Project::find($id);
FindOrFail - в случае отсутствия модели выбросит ровно 404;

4. $this->deleteImageProject($project->logo);
Если вы всегда удаляете лого после удаления модели - то повесьте событие delete и всегда удаляйте лого как только где то и в каком то месте пытаются удалить модель Project. Для случаев mass delete - гляньте в трейт softDeletes, по аналогии можно навешать обработчик.
Лень - через события? Ну переопределите у модели метод delete.
public function delete()
{
    $result = parent::delete();
    if($result){
        $this->deleteImageProject($this->logo);
    }
    return $result;
}

У вас логика удаления модели (если нам надо удалить модель - надо удалить лого) - не должна валяться по всему проекту - она должна лежать в одном месте. А судя повсему вы ее вообще в контроллер запихали - ни в какие ворота

При использовании всего этого у вас метод контроллера приобретет простой и лаконичный вид.

public function destroy(Project $project)
{
    $project->delete();
    return response('', 204);
}


204 - ибо можем

If a DELETE method is successfully applied, the origin server SHOULD
send a 202 (Accepted) status code if the action will likely succeed
but has not yet been enacted, a 204 (No Content) status code if the
action has been enacted and no further information is to be supplied,
or a 200 (OK) status code if the action has been enacted and the
response message includes a representation describing the status.

RFC
Ответ написан
@vism
Да всё верно описал Григорий Васильков , согласен.

lexstile И у вас впринципе то тоже верно

Насчёт ДТО - согласен, но слишком муторно выходит везде ДТО пихать :(
Для ДТО - Spatie DataTransferObject

Я думаю в ПХП 8 простые данные позволительно именованными параметрами передавать
А если данные требуют доп. преобразования, то ДТО

ответ обратно либо стандартным
response()->json()
либо свой обработчик, как Григорий Васильков предложил

вот вариант близкий к вашему написанию. В принципе я так и делаю
public function destroy($id)
    {        
        if (!ProjectPolicy::requestDelete($id)) {
            return response()->json(Response::getErrorMessage('Ошибка доступа'), 403);
        }

        $project = Project::find($id);
        if (!$project) {        
            return response()->json(Response::getErrorMessage('Проект не найден'), 404);
        }
// это вот в сервис класс.
        $project->delete();
        $this->deleteImageProject($project->logo);

        return response()->json(Response::getSuccessMessage('Вы успешно удалили проект'), 200);
    }
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы