Migrations & Schema
Laravel 11 compresses default migrations into fewer files.
Schema::create('orders', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->integer('total_cents');
$table->string('status')->default('pending')->index();
$table->json('metadata')->nullable();
$table->timestamps();
});
Relationships
Defining relationships correctly is key to leveraging Eloquent.
Polymorphic Relationships
Allow a model to belong to more than one other model on a single association.
class Comment extends Model {
public function commentable() {
return $this->morphTo();
}
}
class Post extends Model {
public function comments() {
return $this->morphMany(Comment::class, 'commentable');
}
}
class Video extends Model {
public function comments() {
return $this->morphMany(Comment::class, 'commentable');
}
}
Performance Optimization
The N+1 query problem is the most common performance bottleneck.
Eager Loading
// Bad (N+1 problem)
$books = Book::all();
foreach ($books as $book) {
echo $book->author->name; // Triggers a query for each book
}
// Good (Eager Loading)
$books = Book::with('author')->get(); // 2 queries total
Preventing N+1 in Development
Strict mode helps catch these issues early.
// AppServiceProvider.php
public function boot(): void
{
Model::shouldBeStrict(! $this->app->isProduction());
}
This enables: preventLazyLoading, preventSilentlyDiscardingAttributes, and preventAccessingMissingAttributes.
Scopes
Encapsulate common query logic.
// Local Scope
public function scopeActive(Builder $query): void
{
$query->where('active', 1);
}
// Usage
$users = User::active()->get();
Accessors & Mutators
New syntax using Attribute class.
use Illuminate\Database\Eloquent\Casts\Attribute;
protected function amount(): Attribute
{
return Attribute::make(
get: fn (int $value) => $value / 100,
set: fn (float $value) => $value * 100,
);
}