yudican/laravel-crud-generator
Installation
composer require yudican/laravel-crud-generator
php artisan vendor:publish --provider="Yudican\CrudGenerator\CrudGeneratorServiceProvider" --tag="crud-generator-config"
php artisan migrate
First Use Case
Generate a basic CRUD for a Post model:
php artisan crud:generate Post
database/migrations/..._create_posts_table.php)app/Models/Post.php)app/Http/Controllers/PostController.php)app/Http/Livewire/Posts/Index.php + Create.php/Edit.php)resources/views/livewire/posts/...)routes/web.php)Where to Look First
config/crud-generator.php (adjust table prefixes, default fields, etc.)app/Console/Commands/CrudGenerateCommand.php (customize generation logic)app/Http/Livewire/Posts/ (default CRUD structure)Generate CRUD
php artisan crud:generate Post --fields="title:string,body:text,published:boolean"
Extend Generated Code
app/Models/Post.php after generation.public function getTitleAttribute($value) {
return ucfirst($value);
}
PostController with custom logic (e.g., validation rules).protected function rules() {
return array_merge(parent::rules(), [
'slug' => 'required|unique:posts',
]);
}
Livewire Customization
app/Http/Livewire/Posts/Index.php:public function mount() {
$this->query = $this->query->where('published', true);
}
public function bulkDelete() {
Post::whereIn('id', $this->selected)->delete();
session()->flash('success', 'Posts deleted!');
}
Reusable Components
// app/Http/Livewire/Traits/CrudTrait.php
trait CrudTrait {
public function save() {
$this->validate();
$this->model->save();
session()->flash('success', 'Saved!');
}
}
API Integration
// routes/api.php
Route::apiResource('posts', \App\Http\Controllers\PostController::class);
PostController to support API responses:public function index(Request $request) {
return response()->json($this->livewire('posts.index')->getPosts());
}
Overwriting Existing Files
--force carefully:php artisan crud:generate Post --force
--skip-migration to preserve custom migrations.Livewire Dependency
laravel/livewire). Install if missing:composer require laravel/livewire
Route Conflicts
routes/web.php after generation.Model Binding Issues
PostController uses Post::findOrFail($id), ensure the Livewire component passes the correct ID:// In Edit.php
public $postId;
public function mount($id) {
$this->postId = $id;
}
Generation Errors
storage/logs/laravel.log for CLI command failures.title:string,body:text must use :).Livewire Component Not Loading
app/Providers/AppServiceProvider.php:public function boot() {
Livewire::component('posts.index', \App\Http\Livewire\Posts\Index::class);
}
php artisan view:clear
php artisan cache:clear
Custom Field Types Extend the generator to support custom field types (e.g., rich text, file uploads):
// config/crud-generator.php
'custom_fields' => [
'rich_text' => ['type' => 'textarea', 'attributes' => ['rows' => 5]],
],
Soft Deletes Enable soft deletes in the model and migration:
php artisan crud:generate Post --soft-deletes
deleted_at column and scopeQuery to the model.Authorization Integrate with Laravel’s gates/policies:
// app/Policies/PostPolicy.php
public function update(User $user, Post $post) {
return $user->isAdmin();
}
public function save() {
$this
->authorize('update', $this->post)
->validate()
->save();
}
Testing Use Laravel’s testing helpers to assert CRUD functionality:
public function test_crud_operations() {
$response = $this->get('/posts');
$response->assertStatus(200);
$this->actingAs(user())
->post('/posts', ['title' => 'Test'])
->assertRedirect('/posts');
}
Performance
with() in the Livewire component’s mount():public function mount() {
$this->posts = Post::with('author')->get();
}
paginate(10) instead of get() for large datasets.Localization
Customize labels and messages in resources/lang/en/crud.php:
return [
'posts' => [
'title' => 'Post Title',
'create' => 'New Post',
],
];
<x-input-label>{{ __('crud.posts.title') }}</x-input-label>
How can I help you explore Laravel packages today?