Как избежать дублирования кода в случае похожих сущностей?

Привет.

Хочу разобраться, как правильно реализовать следующее:

Есть несколько сущностей, например, некие партнеры: поставщики, клиенты и т.п. (фактически - это справочники) с одинаковыми полями: название компании , ФИО представителя, должность.

Решение в лоб:
1) сделать для каждой сущности модель с таблицей в БД
2) написать роутеры вида:
Route::resource('clients', 'ClientController');
Route::resource('providers', 'ProviderController');

3) реализовать простейшие контроллеры с добавлением/сохранением/выводом сущностей.

Но на мой взгляд - это плохо: будут одинаковые модели с разным именем, будут одинаковые контроллеры (с той лишь разницей, что данные будут браться из разных моделей). Т.е. фактически код будет дублироваться N раз.

У меня есть 2 идеи как избавиться от дублирования кода:

Первый способ

1) создать одну общую таблицу, добавив в нее поле "type".

2) создать базовый контроллер, в котором реализовать все необходимые методы

3) создать дочерние контроллеры, которые будут наследоваться от базового, и в которых будет указан только тип:

namespace App\Http\Controllers;

class ClientController extends PartnerController
{
    private $type = 'client';
}


namespace App\Http\Controllers;

class ProviderController extends PartnerController
{
    private $type = 'provider';
}


4) Создать роуты вида:
Route::resource('clients', 'ClientController');
Route::resource('providers', ProviderController');


Второй способ

Тоже базовый контроллер со всеми методами. Но тип задавать не в дочерних контроллерах, а брать из url:

Route::resource('partners/{type}', 'PartnerController');


Второй способ мне нравится больше. Хотя стоит сделать оговорку:
указанный resource-route работать не будет, и вместо одной строчки надо будет прописать несколько:
Route::get('partners/{type}', 'PartnerController@index');
Route::get('partners/{type}/create', 'PartnerController@create');
Route::post('partners/{type}', 'PartnerController@store');
Route::get('partners/{type}/{id}/edit', 'PartnerController@edit');
Route::put('partners/{type}/{id}', 'PartnerController@update');
Route::delete('partners/{type}/{id}', 'PartnerController@destroy');


Хорошо ли это? Или есть более адекватные способы?

Кроме того, независимо от способа реализации, у меня вопрос по вьюшкам. Их должно быть 3:
index.blade.php - для вывода списка сущностей
create.blade.php - для создания сущности
edit.blade.php - для изменения сущности.

Во-первых, если выводится список клиентов, то во вьюшке должен быть заголовок "Клиенты", если поставщики - то "Поставщики" и т.д. Как это сделать? Кроме использования switch ничего в голову не приходит.

Во-вторых, на странице со списком сущностей необходимо сделать ссылку на редактирование конкретной сущности конкретного типа. Я придумал только такой способ:
<a class="btn btn-info" href="{{ action('PartnerController@edit', [Request::route()->parameters['type'], $partner->id]) }}">Изменить</a>


Как сделать лучше/правильнее?
  • Вопрос задан
  • 1180 просмотров
Решения вопроса 1
@BorisKorobkov
Web developer
Решение в лоб

Можно, но не нужно.

Первый способ

Да, так гораздо лучше.
Заголовок передавайте вьюшке так же из контроллера.
Ссылку на редактирование конкретной сущности лучше определить в самой модели или в контроллере. Но не во вьюшке.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

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