Laravel 5 全球 CRUD Class
Laravel 5 Global CRUD Class
在有人问之前,我已经研究了 CRUD
生成器并且我知道所有关于 Laravel
资源路由的信息,但这并不是我在这里的目的。
我想要做的是创建一个带有几个参数的路由,以及一个全局 class(uses/extends?)模型控制器用于简单的 CRUD
操作。我们有 20 个左右的模型,为每个 table 创建一个资源 Controller
比找到一种方法来创建全局 CRUD
class 来处理所有“api
" 类型调用和任何 ajax json
请求,如创建/更新/销毁语句。
所以我的问题是什么是构造一个 class 来处理我们所有 Model
的所有 CRUD
请求而无需资源 controller
每 model
?我已经尝试对此进行研究,但似乎找不到任何链接,除了指向 CRUD
生成器的链接和描述 laravel Resource route
.
的链接
最简单的方法是执行以下操作:
为您的资源控制器添加路由:
Route::resource('crud', 'CrudController', array('except' => array('create', 'edit')));
创建您的 crud 控制器
<?php namespace App\Http\Controllers;
use Illuminate\Routing\Controller;
use App\Models\User;
use App\Models\Product;
use Input;
class CrudController extends Controller
{
const MODEL_KEY = 'model';
protected $modelsMapping = [
'user' => User::class,
'product' => Product::class
];
protected function getModel() {
$modelKey = Input::get(static::MODEL_KEY);
if (array_key_exists($modelKey, $this->modelsMapping)) {
return $this->modelsMapping[$modelKey];
}
throw new \InvalidArgumentException('Invalid model');
}
public function index()
{
$model = $this->getModel();
return $model::all();
}
public function store()
{
$model = $this->getModel();
return $model::create(array_except(Input::all(), static::MODEL_KEY));
}
public function show($id)
{
$model = $this->getModel();
return $model::findOrFail($id);
}
public function update($id)
{
$model = $this->getModel();
$object = $model::findOrFail($id);
return $object->update(array_except(Input::all(), static::MODEL_KEY));
}
public function destroy($id)
{
$model = $this->getModel();
return $model::remove($id);
}
}
使用您的新控制器 :) 您必须传递 model 参数,该参数将包含模型密钥 - 它必须是允许的模型之一白名单。例如。如果你想获得 User with id=5 do
GET /crud/5?model=user
请记住它越简单越好,您可能需要使代码更复杂以满足您的需要。
另请记住,此代码尚未经过测试 - 如果您发现任何拼写错误或有其他问题,请告诉我。我很乐意为你拿到它 运行。
您需要一个通用的 class 来执行所有 CRUD
操作,有很多方法可以实现这一点,一个规则可能不适合所有操作,但您可以尝试我将要采用的方法现在描述。这是一个抽象的想法,你需要去实现它,所以一开始,想到所有CRUD操作的URI
。在这种情况下,您必须遵循约定,它可能是这样的:
example.com/user/{id?} // get all or one by id (if id is available in the URI)
example.com/user/create // Show an empty form
example.com/user/edit/10 // Show a form populated with User model
example.com/user/save // Create a new User
example.com/user/save/10 // Update an existing User
example.com/user/delete/10 // Delete an existing User
在这种情况下,user
可能是其他用于指定模型名称的东西,例如 example.com/product/create
并记住这一点,您需要按如下所示声明路由:
Route::get('/{model}/{id?}', 'CrudController@read');
Route::get('/{model}/create', 'CrudController@create');
Route::get('/{model}/edit/{id}', 'CrudController@edit');
Route::post('/{model}/save/{id?}', 'CrudController@save');
Route::post('/{model}/delete/{id}', 'CrudController@delete');
现在,在您的 app\Providers\RouteServiceProvider.php
文件中修改 boot
方法并使其看起来像这样:
public function boot(Router $router)
{
$model = null;
$router->bind('model', function($modelName) use (&$model, &$router)
{
$model = app('\App\User\'.ucfirst($modelName));
if($model)
{
if($id = $router->input('id'))
{
$model = $model->find($id);
}
return $model ?: abort(404);
}
});
parent::boot($router);
}
然后声明您的 CrudController
,如下所示:
class CrudController extends Controller
{
protected $request = null;
public function __construct(Request $request)
{
$this->request = $request;
}
public function read($model)
{
return $model->exists ? $model : $model->all();
}
// Show either an empty form or a form
// populated with the given model atts
public function createOrEdit($model)
{
$classNameArray = explode('\', get_class($model));
$className = strtolower(array_pop($classNameArray));
$view = view($className . '.form');
$view->formAction = "$className/save";
if(is_object($model) && $model->exists)
{
$view->model = $model;
$view->formAction .= "/{$model->id}";
}
return $view;
}
public function save($model)
{
// Validation required so do it
// Make sure each Model has $fillable specified
return $this->model->fill($this->request)->save();
}
public function delete($model)
{
return $this->model->delete();
}
}
由于相同的表单用于创建和更新模型,因此使用类似这样的方式创建表单:
<form action="{{url($formAction)}}" method="POST">
<input
type="text"
class="form-control"
name="first_name" value="{{old('first_name', @$model->first_name)}}"
/>
<input type="Submit" value="Submit" />
{!!csrf_field()!!}
</form>
请记住,每个表格都应该在与模型对应的目录中,对于用户 add/edit,表格应该在 views/user/form.blade.php
中,对于产品模型使用 views/product/form.blade.php
等等.
这会起作用,并且不要忘记在保存模型之前添加验证,并且可以使用模型事件或您想要的任何方式在模型内部完成验证。这只是一个想法,但可能不是最好的方法。
除非你想手动实现CRUD,否则考虑集成一个现成的datagrid,比如phpGrid。
查看集成演练:http://phpgrid.com/example/phpgrid-laravel-5-twitter-bootstrap-3-integration/不需要模型,代码最少。它几乎无所不能。
一个基本的工作 CRUD:
// in a controller
public function index()
{
$dg = new \C_DataGrid("SELECT * FROM orders", "orderNumber", "orders");
$dg->enable_edit("FORM", "CRUD");
$dg->display(false);
$grid = $dg -> get_display(true);
return view('dashboard', ['grid' => $grid]);
}
在有人问之前,我已经研究了 CRUD
生成器并且我知道所有关于 Laravel
资源路由的信息,但这并不是我在这里的目的。
我想要做的是创建一个带有几个参数的路由,以及一个全局 class(uses/extends?)模型控制器用于简单的 CRUD
操作。我们有 20 个左右的模型,为每个 table 创建一个资源 Controller
比找到一种方法来创建全局 CRUD
class 来处理所有“api
" 类型调用和任何 ajax json
请求,如创建/更新/销毁语句。
所以我的问题是什么是构造一个 class 来处理我们所有 Model
的所有 CRUD
请求而无需资源 controller
每 model
?我已经尝试对此进行研究,但似乎找不到任何链接,除了指向 CRUD
生成器的链接和描述 laravel Resource route
.
最简单的方法是执行以下操作:
为您的资源控制器添加路由:
Route::resource('crud', 'CrudController', array('except' => array('create', 'edit')));
创建您的 crud 控制器
<?php namespace App\Http\Controllers; use Illuminate\Routing\Controller; use App\Models\User; use App\Models\Product; use Input; class CrudController extends Controller { const MODEL_KEY = 'model'; protected $modelsMapping = [ 'user' => User::class, 'product' => Product::class ]; protected function getModel() { $modelKey = Input::get(static::MODEL_KEY); if (array_key_exists($modelKey, $this->modelsMapping)) { return $this->modelsMapping[$modelKey]; } throw new \InvalidArgumentException('Invalid model'); } public function index() { $model = $this->getModel(); return $model::all(); } public function store() { $model = $this->getModel(); return $model::create(array_except(Input::all(), static::MODEL_KEY)); } public function show($id) { $model = $this->getModel(); return $model::findOrFail($id); } public function update($id) { $model = $this->getModel(); $object = $model::findOrFail($id); return $object->update(array_except(Input::all(), static::MODEL_KEY)); } public function destroy($id) { $model = $this->getModel(); return $model::remove($id); } }
使用您的新控制器 :) 您必须传递 model 参数,该参数将包含模型密钥 - 它必须是允许的模型之一白名单。例如。如果你想获得 User with id=5 do
GET /crud/5?model=user
请记住它越简单越好,您可能需要使代码更复杂以满足您的需要。
另请记住,此代码尚未经过测试 - 如果您发现任何拼写错误或有其他问题,请告诉我。我很乐意为你拿到它 运行。
您需要一个通用的 class 来执行所有 CRUD
操作,有很多方法可以实现这一点,一个规则可能不适合所有操作,但您可以尝试我将要采用的方法现在描述。这是一个抽象的想法,你需要去实现它,所以一开始,想到所有CRUD操作的URI
。在这种情况下,您必须遵循约定,它可能是这样的:
example.com/user/{id?} // get all or one by id (if id is available in the URI)
example.com/user/create // Show an empty form
example.com/user/edit/10 // Show a form populated with User model
example.com/user/save // Create a new User
example.com/user/save/10 // Update an existing User
example.com/user/delete/10 // Delete an existing User
在这种情况下,user
可能是其他用于指定模型名称的东西,例如 example.com/product/create
并记住这一点,您需要按如下所示声明路由:
Route::get('/{model}/{id?}', 'CrudController@read');
Route::get('/{model}/create', 'CrudController@create');
Route::get('/{model}/edit/{id}', 'CrudController@edit');
Route::post('/{model}/save/{id?}', 'CrudController@save');
Route::post('/{model}/delete/{id}', 'CrudController@delete');
现在,在您的 app\Providers\RouteServiceProvider.php
文件中修改 boot
方法并使其看起来像这样:
public function boot(Router $router)
{
$model = null;
$router->bind('model', function($modelName) use (&$model, &$router)
{
$model = app('\App\User\'.ucfirst($modelName));
if($model)
{
if($id = $router->input('id'))
{
$model = $model->find($id);
}
return $model ?: abort(404);
}
});
parent::boot($router);
}
然后声明您的 CrudController
,如下所示:
class CrudController extends Controller
{
protected $request = null;
public function __construct(Request $request)
{
$this->request = $request;
}
public function read($model)
{
return $model->exists ? $model : $model->all();
}
// Show either an empty form or a form
// populated with the given model atts
public function createOrEdit($model)
{
$classNameArray = explode('\', get_class($model));
$className = strtolower(array_pop($classNameArray));
$view = view($className . '.form');
$view->formAction = "$className/save";
if(is_object($model) && $model->exists)
{
$view->model = $model;
$view->formAction .= "/{$model->id}";
}
return $view;
}
public function save($model)
{
// Validation required so do it
// Make sure each Model has $fillable specified
return $this->model->fill($this->request)->save();
}
public function delete($model)
{
return $this->model->delete();
}
}
由于相同的表单用于创建和更新模型,因此使用类似这样的方式创建表单:
<form action="{{url($formAction)}}" method="POST">
<input
type="text"
class="form-control"
name="first_name" value="{{old('first_name', @$model->first_name)}}"
/>
<input type="Submit" value="Submit" />
{!!csrf_field()!!}
</form>
请记住,每个表格都应该在与模型对应的目录中,对于用户 add/edit,表格应该在 views/user/form.blade.php
中,对于产品模型使用 views/product/form.blade.php
等等.
这会起作用,并且不要忘记在保存模型之前添加验证,并且可以使用模型事件或您想要的任何方式在模型内部完成验证。这只是一个想法,但可能不是最好的方法。
除非你想手动实现CRUD,否则考虑集成一个现成的datagrid,比如phpGrid。
查看集成演练:http://phpgrid.com/example/phpgrid-laravel-5-twitter-bootstrap-3-integration/不需要模型,代码最少。它几乎无所不能。
一个基本的工作 CRUD:
// in a controller
public function index()
{
$dg = new \C_DataGrid("SELECT * FROM orders", "orderNumber", "orders");
$dg->enable_edit("FORM", "CRUD");
$dg->display(false);
$grid = $dg -> get_display(true);
return view('dashboard', ['grid' => $grid]);
}