【发布时间】:2015-05-04 16:09:04
【问题描述】:
我正在尝试为 Laravel 构建一个非常通用的 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()。
到目前为止一切顺利。现在是验证问题:
对于 Article 实体,我将在以下位置定义验证规则:
app/Http/Requests/StoreArticleRequest.php
app/Http/Requests/UpdateArticleRequest.php
但是请求的类已经在 CrudController 中定义了,所以 Laravel 将使用这些类进行类型提示,所以执行的验证将是来自 StoreRequest 的验证,而不是我想要一个,StoreArticleRequest。
如何将这些类传递给 CrudController 中的 create() 和 update() 方法?
不能:
我不想在ArticleController中重新定义create()方法,因为复制粘贴create()函数逻辑每个 EntityController 都会导致重复的代码。此外,它们会有不同的参数,这会触发“应该与”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) {...}
...
}
在 ArticleController 中:
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
}
但它不起作用,因为 ArticleController Laravel 仍然从 CrudController 中定义的 App\Http\Requests\StoreCRUDRequest 运行验证。
知道如何实现这一点吗?
【问题讨论】:
-
另一种理想的解决方案是在 CrudController 中基于变量定义 create 方法,例如: public function store({$store_request_type_name} $request) {}
-
StoreArticleRequest可以从StoreCRUDRequest扩展,通过这种方式,您可以在满足类型提示的每个孩子中注入请求类 -
您找到解决方案了吗?偶然发现这个试图做类似的事情
-
可悲的是,只有一些我不太自豪的事情:在子控制器中,我创建了一些新方法,它们调用父方法。所以在上面的例子中,ArticleController 有 createArticle(StoreRequest $request) 和 updateArticle(UpdateRequest $request),分别调用 parent::create() 和 parent::update()。不是很自豪……但它确实有效。如果你发现别的东西,请告诉我。这真的让我很烦。