Laravel 5全球CRUD课程

时间:2015-07-27 15:39:49

标签: php laravel laravel-5 crud

在有人询问之前,我已经调查了CRUD个生成器,并且我知道所有关于Laravel资源路由的信息,但这并不是我在这里提到的。

我要做的是创建一个带有几个参数的Route,以及一个用于简单CRUD操作的Model控制器(使用/ extends?)的全局类。我们有20个左右的模型,为每个表创建资源Controller比找到创建全局CRUD类来处理所有“api”类型调用的方法更耗时任何ajax json请求,如create / update / destroy语句。

所以我的问题是,构建一个类以处理我们拥有的每个CRUD的所有Model个请求的最简洁和最好的方法是什么,而不必为每个{controller提供资源model {1}}?我已经尝试过对此进行研究,似乎无法找到除CRUD生成器和描述laravel Resource route的链接之外的任何链接。

3 个答案:

答案 0 :(得分:3)

最简单的方法是执行以下操作:

  1. 为资源控制器添加路由:

    Route::resource('crud', 'CrudController', array('except' => array('create', 'edit')));
    
  2. 创建您的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);
        }
    }
    
  3. 使用新控制器:)您必须传递包含模型键的模型参数 - 它必须是白名单中允许的模型之一。例如。如果您希望用户 id = 5 ,请执行

    GET /crud/5?model=user
    
  4. 请记住,尽可能简单,您可能需要使代码更复杂,以满足您的需求。

    请记住,此代码尚未经过测试 - 如果您发现任何拼写错误或有其他问题,请与我们联系。我很乐意让它为你奔跑。

答案 1 :(得分:3)

除非您想手动实现CRUD,否则请考虑集成现成的数据网格,例如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]);
}

答案 2 :(得分:0)

对于所有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>

请记住,每个表单应位于与模型对应的目录中,用户添加/编辑,表单应位于views/user/form.blade.php中,产品型号使用views/product/form.blade.php等等。

这样可以工作,不要忘记在保存模型之前添加验证,并且可以使用模型事件或者您想要的模型内部进行验证。这只是一个想法,但可能不是最佳方式。