Структура действий контроллера Laravel
После просмотра множества laracasts одно утверждение везде: держите контроллер как можно более легким.
Хорошо, я пытаюсь ознакомиться с концепциями и философией Laravel, с репозиторием и шаблонами разделения интересов, и у меня есть несколько вопросов, которые меня беспокоят, давайте предположим следующее:
Route::resource('/item', 'ItemController');
class Item extends \Eloquent {}
репо
class EloquentItemRepo implements ItemRepo {
public function all()
{
return Item::all();
}
public function find($id)
{
return Item::where('id', '=', $id);
}
}
и контроллер:
class ItemController extends BaseController {
protected $item;
public function __construct(ItemRepo $item)
{
$this->item = $item;
}
public function index()
{
$items = $this->item->all();
return Response::json(compact('items'))
}
}
На данный момент все просто и чисто (предположим, что репозиторий загружен провайдерами и т. Д.) Контроллер действительно прост и ничего не делает, кроме загрузки и возврата данных (я использовал json, но все подойдет).
Пожалуйста, предположите, что я использую фильтр авторизации, который проверяет, что пользователь вошел в систему и существует, или возвращает ошибку, если это не так, поэтому мне не нужно делать дополнительную проверку в контроллере.
Теперь, что, если мне нужно сделать больше проверок, например:
Методы response_* являются помощниками, которые форматируют ответ Json
public function destroy($id)
{
try {
if ($this->item->destroy($id)) {
return Response::json(['success' => true]);
}
return response_failure(
Lang::get('errors.api.orders.delete'),
Config::get('status.error.forbidden')
);
} catch (Exception $e) {
return response_failure(
Lang::get('errors.api.orders.not_found'),
Config::get('status.error.notfound')
);
}
}
В этом случае я должен проверить много вещей:
- Смещение сработало? (верните истину)
- Разрушение не удалось? (вернуть ложь)
- Произошла ошибка при удалении? (напр.: элемент не был найден с firstOrFail)
У меня есть методы, где проводится гораздо больше тестов, и у меня сложилось впечатление, что контроллер становится все больше и больше, поэтому я могу справиться с любыми возможными ошибками.
Это правильный способ справиться с этим? Контроллер должен быть полон проверок или тесты должны быть перенесены в другое место?
В провайдере я часто пользуюсь item->firstOrFail()
и пусть исключение всплывает до контроллера, это хорошо?
Если бы кто-то мог указать мне правильное направление, так как все laracasts или другие учебные пособия всегда используют более простой случай, когда не требуется много элементов управления.
Редактирование: Практический кейс
Итак, вот практический случай моего опроса:
контроллер
/**
* Update an order.
* @param int $id Order id.
* @return \Illuminate\Http\JsonResponse
*/
public function update($id)
{
try {
$orderItem = $this->order->update($id, Input::all());
if (false === $orderItem) {
return response_failure(
Lang::get('errors.api.orders.update'),
Config::get('status.error.forbidden')
);
}
return response_success();
} catch (Exception $e) {
return response_failure(
Lang::get('errors.api.orders.not_found'),
Config::get('status.error.notfound')
);
}
}
Сделки рЕПО
public function update($id, $input)
{
$itemId = $input['itemId'];
$quantity = $input['quantity'] ?: 1;
// cannot update without item id
if (!$itemId) {
return false;
}
$catalogItem = CatalogItem::where('hash', '=', $itemId)->firstOrFail();
$orderItem = OrderItem::fromCatalogItem($catalogItem);
// update quantity
$orderItem->quantity = $quantity;
return Order::findOrFail($id)->items()->save($orderItem);
}
В этом случае возможны 3 проблемы:
- заказ не найден
- каталогИмент не найден
- itemId не установлен в данных поста
В способе, который я организовал, проблема в том, что сообщение об ошибке верхнего уровня не будет четким, так как оно всегда будет указывать: "заказ не найден", даже если не найден элемент каталога.
Единственная возможность, которую я вижу, это перехватить несколько кодов исключений в контроллере и вызвать другое сообщение об ошибке, но не перегрузит ли это контроллер?