Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel 5 Global CRUD Class

Before anyone asks, I've looked into CRUD generators and I know all about the Laravel Resource routes, but that's not exactly what I'm pulling for here.

What I'm looking to do is create one Route with a couple parameters, and one global class that (uses/extends?) the Model controller for simple CRUD operations. We have 20 or so Models and creating a Resource Controller for each table would be more time consuming than finding a way to create a global CRUD class to handle all "api" type calls and any ajax json request like a create / update / destroy statement.

So my question is what is the cleanest and best way to structure a class to handle all CRUD requests for every Model we have without having to have a resource controller for every model? I've tried researching this and can't seem to find any links except ones to CRUD generators and links describing the laravel Resource route.

like image 472
jamadri Avatar asked Jul 27 '15 15:07

jamadri


2 Answers

The easiest way would be to do the following:

  1. Add a route for your resource controller:

    Route::resource('crud', 'CrudController', array('except' => array('create', 'edit')));
    
  2. Create your crud controller

    <?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. Use your new controller :) You have to pass the model parameter that will contain the model key - it must be one of the allowed models in the whitelist. E.g. if you want to get a User with id=5 do

    GET /crud/5?model=user
    

Please keep in mind that it's as simple as possible, you might need to make the code more sophisticated to match your needs.

Please also keep in mind that this code has not been tested - let me know if you see any typos or have some other issues. I'll be more than happy to get it running for you.

like image 114
jedrzej.kurylo Avatar answered Oct 09 '22 14:10

jedrzej.kurylo


Unless you want to implement CRUD manually, consider to integrate a ready-made datagrid such as phpGrid.

Check out integration walkthrough: http://phpgrid.com/example/phpgrid-laravel-5-twitter-bootstrap-3-integration/ No models are required and the code is minimum. It can almost do anything.

A basic working 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]);
}
like image 20
Samuel Ev Avatar answered Oct 09 '22 14:10

Samuel Ev