Challenge 1: Create a Model and Migration — Possible Solution ==================================================================== # php artisan make:model Author -m # Model created successfully. # Created Migration: 2026_07_05_130000_create_authors_table.php // database/migrations/2026_07_05_130000_create_authors_table.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('authors', function (Blueprint $table) { $table->id(); $table->string('name'); $table->text('bio')->nullable(); $table->timestamps(); }); } public function down(): void { Schema::dropIfExists('authors'); } }; // app/Models/Author.php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Author extends Model { protected $fillable = ['name', 'bio']; } # Don't forget to actually apply it: # php artisan migrate WHY THIS WORKS -------------- - $table->id() adds the auto-incrementing primary key column — the Eloquent equivalent of Django's implicit id field, generated automatically unless a different primary key is configured. - $table->text('bio')->nullable() marks bio as an optional field at the database level — without ->nullable(), the column would be NOT NULL by default and every Author would require a bio to be saved at all. - $table->timestamps() adds created_at and updated_at columns that Eloquent manages automatically on every save — a convenience with no direct one-line Django equivalent (Django would need auto_now_add/ auto_now set explicitly on two separate fields). - down() calls Schema::dropIfExists('authors') — the exact reverse of up()'s Schema::create('authors', ...) — written by hand here, unlike Django where this reverse operation is generated automatically from the model diff. - $fillable = ['name', 'bio'] is the mass-assignment allowlist from this chapter, set up from the very first version of the model rather than added as an afterthought.