Logo

dev-resources.site

for different kinds of informations.

How to Build a Generic CRUD Controller in Laravel for Multiple Resources

Published at
1/6/2025
Categories
laravel
php
webdev
tutorial
Author
abdullahqasim
Categories
4 categories in total
laravel
open
php
open
webdev
open
tutorial
open
Author
13 person written this
abdullahqasim
open
How to Build a Generic CRUD Controller in Laravel for Multiple Resources

How to Build a Generic CRUD Controller in Laravel for Multiple Resources

Managing multiple CRUD operations in a Laravel application can be overwhelming, especially when handling a growing number of models. In this post, I'll guide you on creating a generic CRUD controller that allows you to handle existing and future CRUD operations in a single controller.

Why Use a Generic Controller?

A generic controller helps:

  • Minimize repetitive code.
  • Make adding new models a breeze.
  • Provide a consistent structure for your application.

Let’s dive into the implementation step by step!


Step 1: Setting Up the Controller

Start by creating a new controller:

php artisan make:controller GenericController
Enter fullscreen mode Exit fullscreen mode

Step 2: Writing the Controller Logic

Here’s how you can design your GenericController to handle CRUD operations for any model:

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Str;

class GenericController extends Controller
{
    protected function getModel($modelName)
    {
        $modelClass = 'App\\Models\\' . Str::studly($modelName);

        if (!class_exists($modelClass)) {
            abort(404, "Model $modelName not found.");
        }

        return new $modelClass;
    }

    public function index($model)
    {
        $modelInstance = $this->getModel($model);
        return response()->json($modelInstance::all());
    }

    public function show($model, $id)
    {
        $modelInstance = $this->getModel($model);
        return response()->json($modelInstance::findOrFail($id));
    }

    public function store(Request $request, $model)
    {
        $modelInstance = $this->getModel($model);
        $data = $request->validate($modelInstance->getFillable());
        $created = $modelInstance::create($data);

        return response()->json($created, 201);
    }

    public function update(Request $request, $model, $id)
    {
        $modelInstance = $this->getModel($model);
        $item = $modelInstance::findOrFail($id);
        $data = $request->validate($modelInstance->getFillable());
        $item->update($data);

        return response()->json($item);
    }

    public function destroy($model, $id)
    {
        $modelInstance = $this->getModel($model);
        $item = $modelInstance::findOrFail($id);
        $item->delete();

        return response()->json(['message' => 'Deleted successfully.']);
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Dynamic Routing

Configure your routes to use dynamic endpoints:

use App\Http\Controllers\GenericController;

Route::controller(GenericController::class)->prefix('api/{model}')->group(function () {
    Route::get('/', 'index'); 
    Route::get('/{id}', 'show'); 
    Route::post('/', 'store'); 
    Route::put('/{id}', 'update'); 
    Route::delete('/{id}', 'destroy'); 
});
Enter fullscreen mode Exit fullscreen mode

Step 4: Prepare Your Models

Ensure each model has:

  • A $fillable property to specify mass-assignable fields.

Example for a Post model:

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;

    protected $fillable = ['title', 'content'];
}

Enter fullscreen mode Exit fullscreen mode

Key Advantages

  • Scalability: Easily handle new models by adding only the model file.
  • Code Reusability: Reduces redundancy.
  • Simplifies Maintenance: Focus on business logic without worrying about boilerplate code.

When to Use This Approach?

This is ideal for:

  • Applications with standard CRUD logic.
  • Projects where models share common behavior.

For more complex business logic, you may still need dedicated controllers.

laravel Article's
30 articles in total
Favicon
Serve a Laravel project on Web, Desktop and Mobile with Tauri
Favicon
Host Header Injection in Laravel: Risks and Prevention
Favicon
Laravel 11.30: A Leap Forward in Testing, Model IDs, and Authorization
Favicon
How to Effectively Manage Laravel Request Validation?
Favicon
[Boost]
Favicon
Building a Quick CSV Export Command in Laravel
Favicon
Deploy laravel application using vercel : Amazing
Favicon
How to Image Upload with CKeditor in Laravel 11 Tutorial
Favicon
How to Install and Use Trix Editor in Laravel 11
Favicon
Testing Temporary URLs in Laravel Storage
Favicon
API Vulnerabilities in Laravel: Identify & Secure Your Endpoints
Favicon
Enforcing Strong Passwords in Laravel
Favicon
Beyond MVC: Redefining Backend Development with DataForge
Favicon
From Product Manager to Independent Developer: A Six-Month Transformation Guide
Favicon
"PHP is dead⚰️" .. what's next? Is Laravel worth it? 😎
Favicon
LTS as a Business: How an Old Project Can Become the Foundation for a New Business Model
Favicon
How to Fix the "PHP Not Found" Error on macOS After Installing XAMPP
Favicon
Sending logs to Telegram. Module for Laravel
Favicon
Need someone to contribute in writing test code for my open source project
Favicon
6 Steps to Master PHPUnit Testing with Ease!
Favicon
How to Create a Reusable Laravel Admin Panel for Multiple Projects
Favicon
Day 6: Building APIs with Laravel Sanctum
Favicon
Fix Insufficient Logging & Monitoring in Laravel Easily
Favicon
πŸŽ‰ Simplify Laravel CRUD Operations with Ease! πŸš€
Favicon
Laravel IQ - Level 1 - Part 2
Favicon
Different ways to use where() in Laravel
Favicon
Laravel IQ - Level 1 - Part 1
Favicon
Leveraging Social Media to Attract Top PHP Developers
Favicon
Laravel Eloquent ORM in Bangla Part-3 (Models Retrieving)
Favicon
How to Build a Generic CRUD Controller in Laravel for Multiple Resources

Featured ones: