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.
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_allmaps 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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
