How to Build a Configurable CRUD Backend in Laravel with Minimal Code

This article explains how to create a Laravel CRUD backend that can be generated entirely from configuration, covering the design of the config file, a reusable FormController, route definitions, controller methods, and Blade view templates for list, create, and edit pages.

Python Programming Learning Circle
Python Programming Learning Circle
Python Programming Learning Circle
How to Build a Configurable CRUD Backend in Laravel with Minimal Code

Configuration is Everything

When building a backend from scratch, most pages involve simple CRUD operations on a single table, which suggests a configuration‑driven approach where a CRUD backend can be generated automatically from a config file.

Designing the Configuration File

The configuration is placed in the controller (instead of a generic config directory or the model) to avoid a monolithic file and to keep the config focused on page presentation.

List Page

The list page includes search, edit, delete, and create buttons.

Create Page

Edit Page

All pages can be configured by extending a base FormController that defines the following protected properties:

class FormController extends BaseController {
    // Corresponding model
    protected $model;
    // All fields with metadata
    protected $fields_all;
    // Fields shown on the list page
    protected $fields_show;
    // Fields shown on the edit page
    protected $fields_edit;
    // Fields shown on the create page
    protected $fields_create;
}
$fields_all

maps database column names to an array containing display name, search capability, and field type. $fields_show, $fields_edit, and $fields_create are subsets of $fields_all that control which columns appear on each view.

Routes

Laravel’s resource routing automatically provides the full set of CRUD routes, reducing boilerplate.

Route::resource('badmin', 'BadminController');

Controller Implementation

The controller inherits from FormController. In the constructor, common data such as the model, field definitions, and request input are shared with the Blade views.

public function __construct()
{
    $route = Route::currentRouteAction();
    list($this->controller, $action) = explode('@', $route);
    View::share('controller', $this->controller);

    $fields_show = [];
    foreach ($this->fields_show as $field) {
        $fields_show[$field] = $this->fields_all[$field];
    }
    View::share('fields_show', $fields_show);

    $fields_edit = [];
    foreach ($this->fields_edit as $field) {
        $fields_edit[$field] = $this->fields_all[$field];
    }
    View::share('fields_edit', $fields_edit);

    $fields_create = [];
    foreach ($this->fields_create as $field) {
        $fields_create[$field] = $this->fields_all[$field];
    }
    View::share('fields_create', $fields_create);

    View::share('input', Input::all());
}

public function index()
{
    $model = new $this->model;
    $builder = $model->orderBy('id', 'desc');
    $input = Input::all();
    foreach ($input as $field => $value) {
        if (empty($value) || !isset($this->fields_all[$field])) continue;
        $search = $this->fields_all[$field];
        $builder->whereRaw($search['search'], [$value]);
    }
    $models = $builder->paginate(20);
    return View::make('form.index', ['models' => $models]);
}

public function create()
{
    return View::make('form.create', []);
}

public function store()
{
    $model = new $this->model;
    $model->fill(Input::all());
    $model->save();
    return Redirect::to(action($this->controller . '@index'));
}

public function edit($id)
{
    $model = (new $this->model)->find($id);
    return View::make('form.edit', compact('model'));
}

public function update($id)
{
    $model = (new $this->model)->find($id);
    $model->fill(Input::all());
    $model->save();
    return Redirect::to(action($this->controller . '@index'));
}

public function destroy($id)
{
    (new $this->model)->destroy($id);
    return Redirect::to(action($this->controller . '@index'));
}

Views

The Blade templates consist of three pages: list, edit, and create. The list view uses Laravel’s pagination and a simple search form. The edit and create views are single forms that iterate over the configured fields.

// Example of a search form in the list view
<form class="form-inline" role="form" action="{{ action($controller . '@index') }}">
    @foreach ($fields_show as $field => $field_info)
        @if (isset($field_info['search']))
            <div class="form-group">
                <label class="col-sm-3 control-label">{{ $field_info['show'] }}</label>
                <input name="{{ $field }}" type="text" class="form-control" value="{{ $input[$field] ?? '' }}" />
            </div>
        @endif
    @endforeach
    <button type="submit" class="btn btn-success">Search</button>
</form>

Delete actions are performed via a hidden _method field set to DELETE. All forms use Laravel’s CSRF protection and follow the RESTful conventions provided by the resource route.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

PHPCRUDLaravelFormControllerResource Routing
Python Programming Learning Circle
Written by

Python Programming Learning Circle

A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.