mr.incognito/crudify
Laravel package to scaffold API or web CRUD via Artisan. Generates models, migrations, controllers, form requests, resources, and optional Blade views. Supports typed validation, nullable fields (~), foreign keys/constraints, defaults, exclude flags, and a delete:crud cleanup command.
To begin using mr.incognito/crudify, install the package via Composer:
composer require mr.incognito/crudify
Start by generating a basic CRUD for a model, e.g., Department, with fields like name and created_by (a nullable foreign key):
php artisan make:crud Department --fields="name:string|max:255;created_by:foreign~|constrained:users"
This creates:
app/Models/Department.php)database/migrations/..._create_departments_table.php)app/Http/Controllers/Api/DepartmentController.php)app/Http/Requests/DepartmentRequest.php)app/Http/Resources/DepartmentResource.php)routes/api.phpFirst Use Case: Quickly scaffold an API for an internal tool (e.g., admin dashboard) without writing boilerplate.
php artisan make:crud User --fields="email:string|email;password:string" --type=api
UserController (e.g., store() for custom logic) while keeping generated code for standard operations.UserRequest to add rules (e.g., unique:users,email,{$user->id} for updates).php artisan make:crud Product --fields="name:string;price:decimal" --type=web
resources/views/products/ (e.g., add Alpine.js for interactivity).ProductRequest for custom authorization (e.g., authorize('update-product')).php artisan make:crud Setting --fields="key:string;value:text" --exclude=migration
Useful for adding CRUD to existing tables or when migrations are managed elsewhere.php artisan make:crud Order --fields="user_id:foreign|constrained:users|onDelete:cascade;product_id:foreign|constrained:products"
php artisan make:crud Comment --fields="user_id:foreign~|constrained:users;post_id:foreign|constrained:posts"
php artisan make:crud Post --fields="title:string;is_published:boolean~|default:false"
nullable, default, and onDelete in one field definition.php artisan make:crud ExistingModel --exclude=model,migration --type=api
routes/api.php or routes/web.php for non-standard endpoints.composer test
test('create department', fn() => $this->post('/api/departments', [...])).Foreign Key Mismatches:
users) are created first.php artisan migrate after generating the CRUD or create the parent table manually.Route Conflicts:
User and Admin) will overwrite routes.--type=web or --type=api explicitly or manually edit routes/api.php/routes/web.php.Blade Template Overwrites:
--exclude=views to preserve them.Nullable Fields in Validation:
~) in the command may still require validation rules in FormRequest. Ensure rules like nullable|string are added.FormRequest to match the nullable status.Default Values in API Resources:
toArray() method in the Resource.Resource to include defaults:
public function toArray($request) {
return array_merge(parent::toArray($request), ['is_published' => true]);
}
Delete Command Limitations:
delete:crud command may skip files if they don’t match expected paths (e.g., custom-named migrations).--force to bypass confirmation or manually delete files.Type Safety in Fields:
date instead of timestamp) may cause migration errors.Check Generated Files:
php artisan migrate --pretend
Validation Errors:
FormRequest (e.g., app/Http/Requests/DepartmentRequest.php) for incorrect rules or missing fields.Route Issues:
routes/api.php or routes/web.php for duplicates.Foreign Key Errors:
php artisan schema:dump
to reset the database schema or manually adjust the migration.Blade Rendering:
php artisan view:clear
Custom Templates:
php artisan vendor:publish --tag=crudify-views
resources/views/vendor/crudify/.Hooks in Controllers:
customLogic()) and calling them in overridden methods like store():
public function store(Request $request) {
$this->customLogic();
return parent::store($request);
}
Dynamic Field Generation:
--fields argument.API Resource Extensions:
Resource:
public function toArray($request) {
return [
'id' => $this->id,
'name' => $this->name,
'full_url' => route('api.products.show', $this),
];
}
Form Request Logic:
handle() method of the FormRequest:
public function handle() {
if (!$this->user()->can('manage', $this->route('model'))) {
abort(403);
}
return parent::handle();
}
Migration Extensions:
Schema::table('departments', function (Blueprint $table) {
$table->index('name');
});
Default Type:
--type=api. Always specify --type=web for Blade-based CRUDs to avoid confusion.Field Syntax:
|) to separate rules (e.g., name:string|max:255|min:3) and semicolons (;) to separate fields.--fields="name:string|max:255;email:string|email|unique:users".Exclude Flag:
--exclude flag accepts comma-separated values (e.g., --exclude=model,migration). Use .. to exclude all remaining components (e.g., --exclude=model,..).Foreign Key Constraints:
id or specify the key explicitly (e.g., `How can I help you explore Laravel packages today?