Eloquent is how almost every Laravel app reads and writes its data.
An Eloquent model is a class in app/Models representing one table: Post maps to posts by convention, with id as the primary key and created_at/updated_at maintained automatically.
Query through the model with a fluent query builder:
$posts = Post::where('published', true)->orderByDesc('created_at')->take(10)->get();get()returns a Collection of models;first()one model or null;find($id)by key;findOrFail($id)throws a ModelNotFoundException, which becomes a 404.count(),exists(),pluck('title'),paginate(15).where('votes', '>', 100),whereIn,whereNull,orWhere, andwhen($cond, fn ($q) => ...)for optional filters.
All values are bound as PDO parameters, so they're safe from SQL injection.
Writing data:
Post::create([...])inserts and returns the model;$post->update([...])changes it;$post->delete()removes it.- Or set attributes and call
$post->save(). firstOrCreateandupdateOrCreatehandle "find or insert" cases.
create and update use mass assignment, so the model must whitelist columns with protected $fillable = ['title', 'body']; (or use $guarded). This stops a malicious request from setting fields such as is_admin.
Define casts in a casts() method to turn columns into proper types: 'published_at' => 'datetime', 'options' => 'array', 'status' => Status::class for an enum.
Example
<?php
namespace App\Models;
use App\Enums\Status;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $fillable = ['title', 'slug', 'body', 'status', 'published_at'];
protected function casts(): array
{
return ['published_at' => 'datetime', 'status' => Status::class];
}
}
// Usage (e.g. in php artisan tinker):
$post = Post::create(['title' => 'Hi', 'slug' => 'hi', 'body' => '...', 'status' => 'draft']);
$post->update(['status' => Status::Published, 'published_at' => now()]);
$recent = Post::where('status', Status::Published)
->where('published_at', '>=', now()->subWeek())
->latest('published_at')
->get(); // Collection of Post models
$titles = $recent->pluck('title'); // Collection of strings
$post->published_at->diffForHumans(); // "1 second ago" (Carbon)
Post::findOrFail(999); // ModelNotFoundException -> 404Remember
- One model per table; conventions decide table and key names
- Chain where/orderBy/take and finish with get, first, find or paginate
- Whitelist $fillable for mass assignment; use casts() for types
Watch out for
- Calling Post::create($request->all()) with a broad $guarded = [], letting users set any column.