Let's practice creating a CRUD with another one: Task Categories. It will be almost the same as Tasks CRUD, so for the most part, I will just show the code and specify the differences.
Task Categories: DB Model/Migration
First, we prepare the back end.
Create Model, Migration, and Pivot table for task categories:
php artisan make:model TaskCategory -mphp artisan make:migration create_task_task_category_table
Migration:
Schema::create('task_categories', function (Blueprint $table) { $table->id(); $table->string('name'); $table->timestamps();});
Pivot migration:
Schema::create('task_task_category', function (Blueprint $table) { $table->foreignId('task_id')->constrained(); $table->foreignId('task_category_id')->constrained();});
app/Models/Task.php:
use Illuminate\Database\Eloquent\Relations\BelongsToMany; // ... public function taskCategories(): BelongsToMany{ return $this->belongsToMany(TaskCategory::class);}
app/Models/TaskCategory.php
namespace App\Models; use Illuminate\Database\Eloquent\Model;use Illuminate\Database\Eloquent\Relations\BelongsToMany; class TaskCategory extends Model{ protected $fillable = ['name']; public function tasks(): BelongsToMany { return $this->belongsToMany(Task::class); }}
Livewire Components and Routes
Create Livewire components:
php artisan make:livewire TaskCategories/Indexphp artisan make:livewire TaskCategories/Createphp artisan make:livewire TaskCategories/Edit
app/Livewire/TaskCategories/Index.php:
use Livewire\Component;use Illuminate\View\View;use App\Models\TaskCategory; class Index extends Component{ public function delete(int $id): void { $taskCategory = TaskCategory::findOrFail($id); if ($taskCategory->tasks()->count() > 0) { $taskCategory->tasks()->detach(); } $taskCategory->delete(); } public function render(): View { return view('livewire.task-categories.index', [ 'taskCategories' => TaskCategory::withCount('tasks')->paginate(5), ]); }}
app/Livewire/TaskCategories/Create.php:
use Livewire\Component;use Illuminate\View\View;use App\Models\TaskCategory;use Livewire\Attributes\Validate; class Create extends Component{ #[Validate('required|string|max:255')] public string $name = ''; public function save(): void { $this->validate(); TaskCategory::create([ 'name' => $this->name, ]); session()->flash('success', 'Task category successfully created.'); $this->redirectRoute('task-categories.index', navigate: true); } public function render(): View { return view('livewire.task-categories.create'); }}
app/Livewire/TaskCategories/Edit.php:
use Livewire\Component;use Illuminate\View\View;use App\Models\TaskCategory;use Livewire\Attributes\Validate; class Edit extends Component{ #[Validate('required|string|max:255')] public string $name; public TaskCategory $taskCategory; public function mount(TaskCategory $taskCategory): void { $this->taskCategory = $taskCategory; $this->name = $taskCategory->name; } public function save(): void { $this->validate(); $this->taskCategory->update([ 'name' => $this->name, ]); session()->flash('success', 'Task category successfully updated.'); $this->redirectRoute('task-categories.index', navigate: true); } public function render(): View { return view('livewire.task-categories.edit'); }}
And assign them routes...