Лучший способ или рефакторинга контроллера создания или восстановления в Laravel

#php #laravel #eloquent

#php #ларавель #красноречивый

Вопрос:

В моем приложении пользователи могут создавать и программно удалять шлюзы, такие как Paypal. Пользователи веб-сайта могут подключиться к шлюзу и совершать платежи.
Я написал логику в транзакции, также блокирующей соответствующую запись (в website поле), которая была удалена пользователем из-за состояния гонки. Прочитайте код для лучшего понимания.

Уже существует (мягко удалено)
Эти шлюзы должны быть проверены администратором, если пользователь отправляет разные website description поля и по сравнению с соответствующей записью, которая уже была проверена, установлена is_verified и rejection_reason null

is_verified ценности:

  • true проверенный
  • false отклоненный
  • null рассматриваемый

Правило: Создайте, если он не существует, Восстановите, если он был удален.

Почему-то я думаю, что мой код не в порядке, и я слишком много думаю или что-то еще (как перфекционист синдром самозванца).

Миграция

 Schema::create('gateways', function (Blueprint $table) {  $table-gt;id();  $table-gt;foreignId('user_id')  -gt;constrained()  -gt;onUpdate('cascade')  -gt;onDelete('cascade');  $table-gt;string('title', 50);  $table-gt;text('description');  $table-gt;string('website')-gt;unique();  $table-gt;enum('wage', Gateway::getWageKeys());  $table-gt;text('rejection_reason')-gt;nullable();  $table-gt;boolean('is_verified')-gt;nullable()-gt;default(null);  $table-gt;boolean('is_blocked')-gt;default(false);  $table-gt;boolean('first_payment')-gt;default(false);  $table-gt;dateTime('free_until')-gt;nullable();  $table-gt;softDeletes();  $table-gt;timestamps(); });  

Контроллер

 /**  * Create a new gateway.  *   * @param AppHttpRequestsStoreGatewayRequest $request  * @return AppHttpResourcesGatewayResource  */ public function create(StoreGatewayRequest $request) {  try {  $gateway = DB::transaction(function () use ($request) {  $gateway = $request-gt;user()-gt;gateways()-gt;onlyTrashed()  -gt;where('website', $request-gt;website)-gt;lockForUpdate()-gt;first();   if (! $gateway) {  return $request-gt;user()-gt;gateways()-gt;create($request-gt;validated());  } else {  if ($gateway-gt;is_blocked)  abort(452);   $gateway-gt;fill($request-gt;validated());   if ($gateway-gt;isDirty('website') || $gateway-gt;isDirty('description')) {  $gateway-gt;rejection_reason = null;  $gateway-gt;is_verified = null;  }   $gateway-gt;deleted_at = null;  $gateway-gt;save();   return $gateway;  }  });  } catch (QueryException $e) {  if ($e-gt;errorInfo[1] === 1062) {  abort(409);  } else {  throw $e;  }  }   return new GatewayResource($gateway); }  

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

1. Я думаю, что вы могли бы перенести заблокированную и проверенную часть логики в красноречивые события. Все эти числа ошибок на самом деле ничего для меня не значат. Константы могли бы сделать код более читаемым. Константы состояния Http уже существуют где-то в HttpFoundation.

2. Также я не уверен в $gateway = DB::transaction этом . Я думаю, что просто DB::transaction отлично работает. Лично я предпочитаю другой способ совершения транзакций ( beginTransaction , commit , rollBack )

3. Что касается использования блокировки базы данных: действительно ли это так важно в данном случае? Может ли пользователь случайно выполнить одно и то же обновление дважды? Если он это сделает, будут ли какие-либо последствия, такие как взимание денег дважды или если база данных выдаст уникальное нарушение ограничений?

4. $gateway-gt;deleted_at = null; $gateway-gt;save(); может быть заменен на $gateway-gt;restore()

5. @IGP Если вы прочитаете код еще раз, обновленный $gateway объект внутри транзакции будет возвращен, потому return new GatewayResource($gateway); что он нужен в качестве ответа на запрос.