DEV Community

macarthurgonde
macarthurgonde

Posted on

Creating Laravel Artisan Command To Generate Model Repository Service Controller for each table automatically.

  1. Custom Artisan Command: Auto Generate Layers

Run:

php artisan make:command GenerateCrudFromDb

Enter fullscreen mode Exit fullscreen mode
  1. Implement the Command
Replace the file app/Console/Commands/GenerateCrudFromDb.php with:
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;

class GenerateCrudFromDb extends Command
{
    protected $signature = 'generate:crud {--table=*}';
    protected $description = 'Automatically generate Model, Repository, Service, Controller for tables';

    public function handle()
    {
        $tables = $this->option('table');

        if (empty($tables)) {
            // If no table specified, get all tables
            $tables = $this->getAllTables();
        }

        foreach ($tables as $table) {
            $this->generateForTable($table);
        }

        $this->info('All CRUD layers generated successfully!');
    }

    protected function getAllTables()
    {
        $database = DB::getDatabaseName();
        $tables = DB::select("SHOW TABLES");
        $tables = array_map(function ($table) use ($database) {
            return $table->{'Tables_in_' . $database};
        }, $tables);
        return $tables;
    }

    protected function generateForTable($table)
    {
        $className = Str::studly(Str::singular($table));
        $modelName = $className;
        $controllerName = $className . 'Controller';
        $repositoryName = $className . 'Repository';
        $serviceName = $className . 'Service';

        $columns = $this->getTableColumns($table);

        $this->createModel($modelName, $columns);
        $this->createRepository($repositoryName, $modelName);
        $this->createService($serviceName, $repositoryName);
        $this->createController($controllerName, $serviceName);

        $this->info("CRUD generated for table: {$table}");
    }

    protected function getTableColumns($table)
    {
        $columns = DB::select("SHOW COLUMNS FROM {$table}");
        $fillable = [];
        foreach ($columns as $column) {
            if (!in_array($column->Field, ['id', 'created_at', 'updated_at', 'deleted_at'])) {
                $fillable[] = $column->Field;
            }
        }
        return $fillable;
    }

    protected function createModel($name, $fillable)
    {
        $modelPath = app_path("Models/{$name}.php");
        if (!File::exists($modelPath)) {
            $fillableArray = implode("','", $fillable);
            $content = "<?php

namespace App\Models;

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

class {$name} extends Model
{
    use HasFactory;

    protected \$guarded = [];
    protected \$fillable = ['{$fillableArray}'];
}
";
            File::put($modelPath, $content);
            $this->info("Model created: {$name}");
        }
    }

    protected function createRepository($name, $model)
    {
        $repoPath = app_path("Repositories/{$name}.php");
        if (!File::exists($repoPath)) {
            $content = "<?php

namespace App\Repositories;

use App\Models\\{$model};

class {$name}
{
    protected \${$model};

    public function __construct({$model} \${$model})
    {
        \$this->{$model} = \${$model};
    }

    public function all() { return \$this->{$model}::all(); }
    public function find(\$id) { return \$this->{$model}::find(\$id); }
    public function create(array \$data) { return \$this->{$model}::create(\$data); }
    public function update(\$id, array \$data) { 
        \$record = \$this->find(\$id); 
        if(\$record) \$record->update(\$data); 
        return \$record; 
    }
    public function delete(\$id) { 
        \$record = \$this->find(\$id); 
        if(\$record) \$record->delete(); 
        return \$record; 
    }
}
";
            File::put($repoPath, $content);
            $this->info("Repository created: {$name}");
        }
    }

    protected function createService($name, $repository)
    {
        $servicePath = app_path("Services/{$name}.php");
        if (!File::exists($servicePath)) {
            $content = "<?php

namespace App\Services;

use App\Repositories\\{$repository};

class {$name}
{
    protected \${$repository};

    public function __construct({$repository} \${$repository})
    {
        \$this->{$repository} = \${$repository};
    }

    public function all() { return \$this->{$repository}->all(); }
    public function find(\$id) { return \$this->{$repository}->find(\$id); }
    public function create(array \$data) { return \$this->{$repository}->create(\$data); }
    public function update(\$id, array \$data) { return \$this->{$repository}->update(\$id, \$data); }
    public function delete(\$id) { return \$this->{$repository}->delete(\$id); }
}
";
            File::put($servicePath, $content);
            $this->info("Service created: {$name}");
        }
    }

    protected function createController($name, $service)
    {
        $controllerPath = app_path("Http/Controllers/{$name}.php");
        if (!File::exists($controllerPath)) {
            $content = "<?php

namespace App\Http\Controllers;

use App\Services\\{$service};
use Illuminate\Http\Request;

class {$name} extends Controller
{
    protected \${$service};

    public function __construct({$service} \${$service})
    {
        \$this->{$service} = \${$service};
    }

    public function index() { return \$this->{$service}->all(); }
    public function store(Request \$request) { return \$this->{$service}->create(\$request->all()); }
    public function show(\$id) { return \$this->{$service}->find(\$id); }
    public function update(Request \$request, \$id) { return \$this->{$service}->update(\$id, \$request->all()); }
    public function destroy(\$id) { return \$this->{$service}->delete(\$id); }
}
";
            File::put($controllerPath, $content);
            $this->info("Controller created: {$name}");
        }
    }
}
Enter fullscreen mode Exit fullscreen mode
  1. Directory Setup

Make sure these exist:

app/Models
app/Repositories
app/Services
app/Http/Controllers

  1. Usage

Generate for all tables in the database:

php artisan generate:crud

Enter fullscreen mode Exit fullscreen mode

Generate for specific tables:

php artisan generate:crud --table=customers --table=orders

Enter fullscreen mode Exit fullscreen mode

This will automatically create:

Models with $fillable from table columns

Repositories

Services

Controllers
Enter fullscreen mode Exit fullscreen mode

All following the Repository-Service pattern.

Top comments (0)