问题描述
我正在尝试将代码重构为更可重用。
我创建了一个特征CrudControllerTrait来实现index,show,store,update,destroy方法。 但是我发现了两个问题:
BrandController.PHP
public function store(BrandNewRequest $request)
{
$requestData = $request->validated();
return new BrandResource($this->brands->store($requestData));
}
ProductController.PHP
public function store(ProductNewRequest $request)
{
$requestData = $request->validated();
return new ProductResource($this->products->store($requestData));
}
特征方法将是:
public function store(xxxxx $request)
{
$requestData = $request->validated();
return new xxxxxResource($this->repository()->store($requestData));
}
问题1:提示类型。如何提取它们?如果我删除它,则表明该错误:
"message": "Too few arguments to function App\\Http\\Controllers\\BrandController::store(),0 passed and exactly 1 expected"
问题2:返回资源。如何创建新资源?在集合上,我可以解决此问题:
public function index()
{
$models = $this->repository()->index();
return $this->resource()::collection($models);
}
该资源位于使用该特征的控制器上
public function resource()
{
return BrandResource::class;
}
但是只有一种资源不知道该怎么做...
我的想法是,我有很多控制器使用相同的模式:BrandController,ProductController等。我很想在相同的特征上重用这5种方法。
解决方法
我发现的唯一方法是创建一个抽象方法。
trait CrudRepositoryTrait
{
abstract function model();
public function index()
{
return $this->model()::with($this->with())->get();
}
public function find($id)
{
return $this->model()::findOrFail($id);
}
public function store($data)
{
$request = $this->dtoRequest($data);
return $this->model()::create($request);
}
(...)
}
然后是如何使用这种待遇的示例:
class ProductRepository implements ProductRepositoryContract
{
use CrudRepositoryTrait;
function model()
{
return Product::class;
}
(...)
}
通过这种方式,我可以重用很多代码。