Краткий ответ:
Bindings.
Один Route::model
.
И одна Простая привязка для каждого типа запроса формы с использованием интерфейсов для внедрения метода в контроллер .
Длинный ответ применительно к вашему примеру:
Связывание моделей в routes/web.php
:
<?php
Route::model('example', App\Example::class);
Route::resource('example', 'Admin\ExampleController');
Запрашивает привязки в базе контроллеров:
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class BaseController extends Controller
{
// Your code...
/**
* @var string[]|callable[]
*/
protected $bindings = [];
/**
* Controller constructor.
*/
public function __construct()
{
$this->addBindings();
}
/**
* Add controller specific bindings.
*/
protected function addBindings()
{
$app = Container::getInstance();
foreach ($this->getBindings() as $abstract => $concrete) {
$app->bind($abstract, $concrete);
}
}
// Your code...
public function store(Requests\StoreRequestInterface $request)
{
// Your code...
}
public function show(Model $item)
{
// Your code...
}
public function edit(Model $item)
{
// Your code...
}
public function update(Requests\UpdateRequestInterface $request, Model $model)
{
// Your code...
}
public function status(Requests\StatusRequestInterface $request, Model $model)
{
// Your code...
}
public function destroy(Model $item)
{
// Your code...
}
// Your code...
}
И пример контроллера:
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Requests;
class ExampleController extends BaseController
{
// Your code...
/**
* @var string[]|callable[]
*/
protected $bindings = [
Requests\StatusRequestInterface::class => Requests\ExampleStatusRequest::class,
Requests\StoreRequestInterface::class => Requests\ExampleStoreRequest::class,
Requests\UpdateRequestInterface::class => Requests\ExampleUpdateRequest::class,
];
// Your code...
}
Таким образом, интерфейсы Requests будут выглядеть примерно так:
<?php
namespace App\Http\Requests;
interface StoreRequestInterface
{
}
И вы должны использовать его как интерфейс в запросах формы:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ExampleStoreRequest extends FormRequest implements StoreRequestInterface
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return false;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
//
];
}
}
Мнение альтернативного ответа:
Общая база контроллера:
<?php
namespace App\Http\Controllers;
use Illuminate\Container\Container;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
abstract class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
/**
* The view subdirectory that must be used.
*
* @var string
*/
protected $viewDir;
/**
* Bindings
*
* @var string[]|callable[]
*/
protected $bindings = [];
/**
* Controller constructor.
*/
public function __construct()
{
$this->addViewPath();
$this->addBindings();
$this->init();
}
/**
* @return void
*/
protected function init()
{
//
}
/**
* @return string
*/
protected function getViewDir()
{
return $this->viewDir;
}
/**
* @return callable[]|string[]
*/
protected function getBindings()
{
return $this->bindings;
}
/**
* Add controller specific view path.
*/
protected function addViewPath()
{
if (null !== ($dir = $this->getViewDir()) && ($path = realpath(base_path('resources/views/' . $dir)))) {
view()->getFinder()->addLocation($path);
}
}
/**
* Add controller specific bindings.
*/
protected function addBindings()
{
$app = Container::getInstance();
foreach ($this->getBindings() as $abstract => $concrete) {
$app->bind($abstract, $concrete);
}
}
}
База контроллеров ресурсов:
<?php
namespace App\Http\Controllers;
use Illuminate\Database\Eloquent\Model;
use App\Http\Requests\StoreRequestInterface;
use App\Http\Requests\UpdateRequestInterface;
use App\Http\Requests\StatusRequestInterface;
abstract class ResourceController extends Controller
{
/**
* Model class
*
* @var string
*/
protected $modelClass;
/**
* @var string
*/
protected $viewDirPrefix;
/**
* @return string
*/
protected function getViewDir()
{
return $this->viewDir ?:
ltrim($this->viewDirPrefix . DIRECTORY_SEPARATOR . 'pages', DIRECTORY_SEPARATOR) .
DIRECTORY_SEPARATOR . strtolower(class_basename($this->modelClass));
}
/**
* @return \Illuminate\Database\Eloquent\Builder
*/
protected function getQuery()
{
return call_user_func($this->modelClass . '::query');
}
/**
* @return string
*/
protected function getName()
{
return __(class_basename($this->modelClass));
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
protected function index()
{
$title = __('resource.title.index', ['name' => str_plural($this->getName())]);
$models = $this->getQuery()->paginate();
return view('index', compact('title', 'models'));
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
protected function create()
{
$title = __('resource.title.create', ['name' => $this->getName()]);
return view('create', compact('title'));
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request|StoreRequestInterface $request
*
* @return \Illuminate\Http\Response
*/
public function store(StoreRequestInterface $request)
{
$model = $this->getQuery()->create($request->all());
return redirect()
->route(substr($request->route()->getName(), 0, -5) . 'show', $model);
}
/**
* Display the specified resource.
*
* @param \Illuminate\Database\Eloquent\Model $model
*
* @return \Illuminate\Http\Response
*/
public function show(Model $model)
{
$title = __('resource.title.show', ['name' => $this->getName()]);
return view('show', compact('title', 'model'));
}
/**
* Show the form for editing the specified resource.
*
* @param \Illuminate\Database\Eloquent\Model $model
*
* @return \Illuminate\Http\Response
*/
public function edit(Model $model)
{
$title = __('resource.title.edit', ['name' => $this->getName()]);
return view('edit', compact('title', 'model'));
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request|UpdateRequestInterface $request
* @param \Illuminate\Database\Eloquent\Model $model
*
* @return \Illuminate\Http\Response
*/
public function update(UpdateRequestInterface $request, Model $model)
{
$model->update($request->except(['_token', '_method']));
return redirect()
->route(substr($request->route()->getName(), 0, -6) . 'show', $model);
}
/**
* Remove the specified resource from storage.
*
* @param \Illuminate\Database\Eloquent\Model $model
*
* @return \Illuminate\Http\Response
* @throws \Exception
*/
public function destroy(Model $model)
{
$model->delete();
return redirect()
->route(substr(request()->route()->getName(), 0, -7) . 'index');
}
/**
* @param \Illuminate\Http\Request|StatusRequestInterface $request
* @param \Illuminate\Database\Eloquent\Model $model
*
* @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse
*/
protected function status(StatusRequestInterface $request, Model $model)
{
$model->update($request->except('_method'));
return response()->json([
'message' => __('resource.status.success'),
]);
}
}
Контроллер ресурсов для Example
модели:
<?php
namespace App\Http\Controllers\Admin;
use App\Example;
use App\Http\Requests;
use App\Http\Controllers\ResourceController;
class ExampleController extends ResourceController
{
/**
* Model class
*
* @var string
*/
protected $modelClass = Example::class;
/**
* @var string
*/
protected $viewDirPrefix = 'admin';
/**
* @var string[]|callable[]
*/
protected $bindings = [
Requests\StatusRequestInterface::class => Requests\Example\StatusRequest::class,
Requests\StoreRequestInterface::class => Requests\Example\StoreRequest::class,
Requests\UpdateRequestInterface::class => Requests\Example\UpdateRequest::class,
];
}
Файл английского языка в resources/lang/en/resource.php
:
<?php
return [
'title' => [
'index' => 'All :Name',
'create' => 'Create :Name',
'show' => 'Show :Name',
'edit' => 'Edit :Name',
],
'status' => [
'success' => 'Status updated successfully',
],
];
Файл на португальском языке в resources/lang/pt/resource.php
:
<?php
return [
'title' => [
'index' => 'Todos os :Name',
'create' => 'Cadastrar :Name',
'show' => 'Show :Name',
'edit' => 'Editar :Name',
],
'status' => [
'success' => 'O status foi alterado com sucesso',
],
];
Веб-маршруты в routes/web.php
:
<?php
Route::group([
'as' => 'admin.',
'prefix' => 'admin',
'namespace' => 'Admin',
], function () {
Route::model('example', App\Example::class);
Route::resource('example', 'ExampleController');
});
Интерфейсы запроса (для привязки):
<?php
namespace App\Http\Requests;
interface StoreRequestInterface
{
}
То же самое для App\Http\Requests\UpdateRequestInterface
и App\Http\Requests\StatusRequestInterface
...
Пример запроса формы:
<?php
namespace App\Http\Requests\Example;
use Illuminate\Foundation\Http\FormRequest;
use App\Http\Requests\StoreRequestInterface;
class StoreRequest extends FormRequest implements StoreRequestInterface
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return false;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
//
];
}
}
То же самое для App\Http\Requests\Example\UpdateRequest
и App\Http\Requests\Example\StatusRequest
...
Документация, примененная для этого ответа:
Примечание: Этот ответ предназначен для Laravel 5.6. Некоторый код, используемый в этом ответе, не поддерживается в предварительных версиях. Если вам нужна конкретная версия, дайте мне знать, и я постараюсь адаптировать ее.