我正试着为拉雷维尔构建一个非常通用的crud,但我一直在验证。
我有一个restful资源控制器,它将处理任何实体的基本操作:
class CrudController extends Controller {
public function store(StoreRequest $request) {...}
public function update(UpdateRequest $request) {...}
...
}
每个实体都有自己的控制器来扩展它,例如:
articleController扩展了crudcontroller
categorycontroller扩展了crudcontroller
tagcontroller扩展了crudcontroller
因此,当您在articleController()中调用create()方法时,它基本上会调用crudcontroller::create()。
到现在为止,一直都还不错。现在是验证问题:
对于文章实体,我将在下面定义验证规则:
app/http/requests/storearticlequest.php
app/http/requests/updateArticlerequest.php
但是请求的类已经在crudcontroller中定义,因此laravel将使用这些类进行类型提示,因此执行的验证将是来自storerequest的验证,而不是我想要的storearticlerequest。
如何将这些类传递给crudcontroller中的create()和update()方法?
做不到:
我不想重新定义articleController中的create()方法,因为复制粘贴每个entitycontroller中的create()函数逻辑将导致重复的代码。此外,它们将有不同的参数,这将触发“应该与”php错误。
已经尝试过:
在crudcontroller中:
use App\Http\Requests\StoreCRUDRequest as StoreRequest;
use App\Http\Requests\UpdateCRUDRequest as UpdateRequest;
class CrudController extends Controller {
public function store(StoreRequest $request) {...}
public function update(UpdateRequest $request) {...}
...
}
文章控制者:
use App\Http\Requests\StoreArticleRequest as StoreRequest;
use App\Http\Requests\UpdateArticleRequest as UpdateRequest;
class ArticleController extends CrudController {
...
// the create() and store() methods are no longer defined here
}
但它不起作用,因为ArticleControllerLaravel仍然运行在crudcontroller中定义的app\http\requests\storecrudrequest中的验证。
你知道我该怎么做吗?
最佳答案
有什么理由不将请求对象传递到构造函数并让laravel在运行时注入它们?
例子:
<?php
class ArticleController extends CrudController {
use CreateOperation;
public function __construct(StoreArticleRequest $storeRequest, UpdateArticleRequest $updateRequest)
{
$this->storeRequest = $storeRequest;
$this->updateRequest = $updateRequest;
parent::__construct();
}
}
trait CreateOperation
{
/**
* @var Request
*/
private $storeRequest;
public function setStoreRequest(Request $storeRequest): void
{
$this->storeRequest = $storeRequest;
}
public function storeCrud() // parameter removed
{
$request = $this->storeRequest;
...
...
}
}