born-mt / laravel-crud-generator
A Symfony-style interactive entity generator for Laravel with models, migrations, and relationships
Installs: 20
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/born-mt/laravel-crud-generator
Requires
- php: ^8.1|^8.2|^8.3
- illuminate/console: ^10.0|^11.0|^12.0
- illuminate/filesystem: ^10.0|^11.0|^12.0
- illuminate/support: ^10.0|^11.0|^12.0
Requires (Dev)
- larastan/larastan: ^3.0
- orchestra/testbench: ^8.0|^9.0|^10.0
- phpunit/phpunit: ^10.5|^11.0
README
A Symfony-style interactive entity generator for Laravel that streamlines model and migration creation with an intuitive, step-by-step interface.
Table of Contents
Features
- Interactive command-line interface inspired by Symfony's
make:entity - Generate Eloquent models with properties, relationships, casts, and guarded attributes
- Automatically create database migrations with all columns and indexes
- Generate CRUD controllers - Web resource and/or API resource controllers
- Support for various field types (string, integer, boolean, date, json, etc.)
- Built-in relationship handling (belongsTo, hasMany, hasOne, belongsToMany, morphTo, morphMany)
- Update existing models and migrations
- Smart property detection when updating existing entities
- Configurable defaults via config file
- Comprehensive test coverage
Installation
Install the package via Composer:
composer require born-mt/laravel-crud-generator
The package will auto-register via Laravel's package discovery.
Publish Configuration (Optional)
Publish the config file to customize defaults:
php artisan vendor:publish --tag=crud-generator-config
This will create config/crud-generator.php where you can customize:
- Model namespace
- Default string length
- Timestamps behavior
- Soft deletes prompts
- UUID usage
Updating the Package
To update to the latest version:
composer update born-mt/laravel-crud-generator
Usage
Basic Usage
Create a new entity:
php artisan make:entity Product
Interactive Flow Example
$ php artisan make:entity Product Creating a new entity: Product New property name (press <return> to stop adding fields): > name Field type (string, text, integer, boolean, date, datetime, json, belongsTo, hasMany, etc.): > string Length [255]: > 255 Can this field be null in the database? (yes/no) [no]: > no Should this field be unique? (yes/no) [no]: > no New property name (press <return> to stop adding fields): > price Field type: > decimal Precision [8]: > 10 Scale [2]: > 2 Can this field be null in the database? (yes/no) [no]: > no New property name (press <return> to stop adding fields): > category Field type: > belongsTo Related model name: > Category What should the inverse relationship be called? > products On delete action (cascade, set null, restrict) [restrict]: > cascade New property name (press <return> to stop adding fields): > ✓ Model created: app/Models/Product.php ✓ Migration created: database/migrations/2024_10_23_120000_create_products_table.php Success! Next steps: - Review your model and migration - Run: php artisan migrate
Updating Existing Entities
Update an existing model with new fields:
php artisan make:entity Product --update
When updating an existing entity:
- The command loads existing properties from the model
- You can add new properties interactively
- The model file is updated with new casts and relationships
- A new migration file is created to add the new columns
- The migration's
down()method will properly drop the new columns if rolled back
Example update flow:
$ php artisan make:entity Product --update Creating a new entity: Product Loading existing model properties... Found 3 existing properties in the model. New property name (press <return> to stop adding fields): > stock_quantity Field type: > integer Should this field be unsigned? (yes/no) [yes]: > yes Can this field be null in the database? (yes/no) [no]: > no New property name (press <return> to stop adding fields): > Adding 1 new properties to the model. ✓ Model updated: app/Models/Product.php ✓ Migration created: database/migrations/2024_10_23_123456_add_fields_to_products_table.php Success! Next steps: - Review your model and migration - Run: php artisan migrate (to add the new columns)
Force Overwrite
Overwrite existing files:
php artisan make:entity Product --force
Generating Controllers
The package can automatically generate controllers after creating your entity:
Interactive Prompt (Recommended)
When creating an entity, you'll be prompted:
$ php artisan make:entity Product # ... (field creation process) ... Do you want to generate controllers? (yes/no) [no]: > yes Controller Options: Generate web resource controller? (yes/no) [yes]: > yes Generate API resource controller? (yes/no) [no]: > yes ✓ Model created: app/Models/Product.php ✓ Migration created: database/migrations/2024_10_23_120000_create_products_table.php ✓ Web controller created: app/Http/Controllers/ProductController.php ✓ API controller created: app/Http/Controllers/Api/ProductController.php Success! Next steps: - Review your model and migration - Run: php artisan migrate - Review your generated controllers - Add routes for web controller in routes/web.php - Add routes for API controller in routes/api.php
Using Flags
Generate specific controller types using command flags:
# Generate web resource controller only php artisan make:entity Product --web # Generate API resource controller only php artisan make:entity Product --api # Generate both php artisan make:entity Product --web --api # Prompt for controller options php artisan make:entity Product --controller
What Gets Generated
Web Resource Controller (app/Http/Controllers/ProductController.php):
Full CRUD implementation with:
index()- Display paginated listing with viewscreate()- Show creation formstore()- Validate and create new record, redirect with success messageshow()- Display single resourceedit()- Show edit formupdate()- Validate and update record, redirect with success messagedestroy()- Delete record, redirect with success message
Generated controller includes:
public function index(): View { $products = Product::latest()->paginate(15); return view('products.index', compact('products')); } public function store(Request $request): RedirectResponse { $validated = $request->validate([ // Add your validation rules here ]); $product = Product::create($validated); return redirect() ->route('products.show', $product) ->with('success', 'Product created successfully.'); } // ... and more
API Resource Controller (app/Http/Controllers/Api/ProductController.php):
RESTful JSON API with:
index()- Return paginated JSON listingstore()- Validate, create, and return JSON response with 201 statusshow()- Return single resource as JSONupdate()- Validate, update, and return JSON responsedestroy()- Delete and return success JSON
Generated controller includes:
public function index(): JsonResponse { $products = Product::latest()->paginate(15); return response()->json($products); } public function store(Request $request): JsonResponse { $validated = $request->validate([ // Add your validation rules here ]); $product = Product::create($validated); return response()->json([ 'message' => 'Product created successfully.', 'data' => $product, ], 201); } // ... and more
Key Features:
- ✅ Full CRUD operations pre-implemented
- ✅ Proper HTTP status codes (API)
- ✅ Validation placeholders ready to customize
- ✅ Success messages and redirects (Web)
- ✅ Route model binding
- ✅ Pagination support
- ✅ Latest records first (descending order)
- ✅ Type-hinted return types
- ✅ PSR-12 compliant code
How Updates Work
When you run php artisan make:entity YourModel --update, the package:
- Parses the existing model - Extracts existing properties from the
$castsarray and relationship methods - Shows existing properties - Displays a count of properties already in the model
- Collects new properties - Allows you to add new fields interactively (skips properties that already exist)
- Updates the model file - Merges new properties into:
$castsarray (adds new type casts)- Import statements (adds new relationship imports if needed)
- Relationship methods (appends new methods to the end of the class)
- Generates an update migration - Creates a new migration with:
up()method: UsesSchema::table()to add only new columnsdown()method: UsesdropColumn()to remove the new columns if rolled back
The original model structure is preserved - only new casts and relationships are appended.
Supported Field Types
Basic Types
string- VARCHAR (configurable length, default 255)text- TEXTinteger- INTEGERbigInteger- BIGINTboolean- BOOLEANdecimal- DECIMAL (configurable precision and scale)float- FLOATdate- DATEdatetime- DATETIMEtimestamp- TIMESTAMPjson- JSONuuid- UUID
Relationship Types
belongsTo- Many-to-One (creates foreign key in migration)hasMany- One-to-Many (no migration changes)hasOne- One-to-One (no migration changes)belongsToMany- Many-to-Many (prompts for pivot table info)morphTo- Polymorphic relationmorphMany- Polymorphic one-to-many
Field Options
For each property, you can specify:
- Length (string types): Custom length, default 255
- Nullable: Whether the field can be null
- Unique: Whether to add a unique constraint
- Default value: Optional default value
- Unsigned: For integer types
- Index: Whether to add an index
- Precision/Scale: For decimal types
For relationships:
- Related model name
- Foreign key name (with smart defaults)
- Inverse relationship method name
- On delete action (cascade, set null, restrict)
Configuration
The package comes with a configuration file that can be published:
php artisan vendor:publish --tag=crud-generator-config
Configuration options (config/crud-generator.php):
return [ // Default namespace for generated models 'model_namespace' => 'App\\Models', // Default length for string fields 'default_string_length' => 255, // Auto-add timestamps 'timestamps' => true, // Prompt for soft deletes 'soft_deletes' => false, // Use UUIDs instead of auto-increment IDs 'use_uuids' => false, ];
Generated Files
Model File
The command generates a complete Eloquent model with:
- Proper namespace and imports
$guardedarray protecting only the primary key (prevents model bloat)$castsarray with appropriate type casts- Relationship methods
- Clean, PSR-12 compliant code
Example:
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Product extends Model { protected $guarded = ['id']; protected $casts = [ 'price' => 'decimal:2', 'created_at' => 'datetime', 'updated_at' => 'datetime', ]; // Relationships public function category() { return $this->belongsTo(Category::class); } }
Migration File
The command generates a migration with:
- Proper table creation/modification
- All columns with appropriate types and modifiers
- Foreign key constraints
- Indexes
- Timestamps (if enabled)
Example:
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { public function up(): void { Schema::create('products', function (Blueprint $table) { $table->id(); $table->string('name', 255); $table->decimal('price', 10, 2); $table->foreignId('category_id')->constrained('categories')->onDelete('cascade'); $table->timestamps(); }); } public function down(): void { Schema::dropIfExists('products'); } };
Requirements
- PHP ^8.1, ^8.2, or ^8.3
- Laravel ^10.0, ^11.0, or ^12.0
Development
Running Tests
The package includes comprehensive unit and feature tests to ensure reliability.
From the package directory:
cd packages/born-mt/laravel-crud-generator composer install composer test
Or run specific test suites:
# Run only unit tests vendor/bin/phpunit --testsuite=Unit # Run only feature tests vendor/bin/phpunit --testsuite=Feature # Run with coverage (requires Xdebug) composer test:coverage
Static Analysis
The package uses Larastan (PHPStan for Laravel) to ensure code quality and type safety.
# Run static analysis composer analyse # Generate a baseline (useful when adding Larastan to existing code) composer analyse:baseline
The analysis runs at level 6 (out of 9) to balance strictness with practicality. The baseline file (phpstan-baseline.neon) tracks existing issues that will be addressed incrementally.
Test Coverage
The test suite includes:
Unit Tests:
InteractsWithPropertiesTest- Property validation, parsing, and type conversionsGeneratesModelsTest- Model content generation and updatesGeneratesMigrationsTest- Migration generation and field buildingHandlesRelationshipsTest- Relationship method generation
Feature Tests:
CreateEntityTest- End-to-end entity creation with various field typesUpdateEntityTest- Entity updates, new fields, and relationshipsErrorCasesTest- Error handling, validation, and edge cases
All major functionality is covered including:
- Field type conversions
- Constraint handling (nullable, unique, default values)
- Relationship generation (belongsTo, hasMany, hasOne, belongsToMany, morphTo, morphMany)
- Model updates and merging
- Migration generation and rollbacks
- Error cases and validation
Contributing
We welcome contributions! Please see CONTRIBUTING.md for details on:
- Reporting bugs
- Suggesting enhancements
- Submitting pull requests
- Development setup
- Running tests
- Code style guidelines
Security
If you discover any security-related issues, please email info@bornmt.com instead of using the issue tracker.
Credits
- Born MT - Initial development
- Contributors - Thank you to all who have contributed to this project
- Inspiration - Symfony's excellent
make:entitycommand
License
The MIT License (MIT). Please see License File for more information.