Basic Retrieval
| Method |
Description / Example |
all() |
Get all records: User::all() |
get() |
Execute query, return Collection: User::where(...)->get() |
find($id) |
Find by primary key: User::find(1) |
find([$ids]) |
Find multiple: User::find([1, 2, 3]) |
findOr($id, $cb) |
Find or execute callback: User::findOr(1, fn() => ...) |
findOrFail($id) |
Find or throw ModelNotFoundException |
first() |
Get first result or null |
firstOr($cb) |
First or execute callback |
firstOrFail() |
First or throw exception |
sole() |
Get only one result, throw if 0 or 2+ |
firstWhere() |
User::firstWhere('email', $email) |
Value Extraction
| Method |
Description / Example |
value($col) |
Single value: User::where(...)->value('email') |
pluck($col) |
Collection of values: User::pluck('name') |
pluck($val, $key) |
Keyed: User::pluck('name', 'id') → [1=>'John'] |
implode($col, $sep) |
Join values: User::pluck('name')->implode(', ') |
Tip: pluck() with two args creates associative array, perfect for dropdowns.
Where Clauses
| Method |
Description / Example |
where($col, $val) |
User::where('status', 'active') |
where($col, $op, $val) |
User::where('age', '>=', 18) |
where([...]) |
User::where(['status' => 'active', 'role' => 'admin']) |
orWhere() |
->orWhere('role', 'admin') |
where(fn($q) => ...) |
Grouped: ->where(fn($q) => $q->where(...)->orWhere(...)) |
whereNot() |
User::whereNot('status', 'banned') |
whereAny() |
User::whereAny(['name','email'], 'like', '%john%') |
whereAll() |
All columns must match condition |
Where Variations
| Method |
Description / Example |
whereIn($col, $arr) |
User::whereIn('id', [1, 2, 3]) |
whereNotIn() |
User::whereNotIn('status', ['banned', 'deleted']) |
whereNull($col) |
User::whereNull('deleted_at') |
whereNotNull() |
User::whereNotNull('verified_at') |
whereBetween() |
User::whereBetween('age', [18, 65]) |
whereNotBetween() |
Exclude range |
whereBetweenColumns() |
->whereBetweenColumns('weight', ['min', 'max']) |
Date/Time Where
| Method |
Description / Example |
whereDate() |
Order::whereDate('created_at', '2025-01-15') |
whereMonth() |
Order::whereMonth('created_at', 12) |
whereDay() |
Order::whereDay('created_at', 25) |
whereYear() |
Order::whereYear('created_at', 2025) |
whereTime() |
Order::whereTime('created_at', '>', '09:00') |
Tip: Use Carbon for dynamic dates: whereDate('created_at', now())
Column Comparisons
| Method |
Description / Example |
whereColumn() |
->whereColumn('updated_at', '>', 'created_at') |
whereColumn([...]) |
->whereColumn([['a', '=', 'b'], ['c', '>', 'd']]) |
JSON Where (MySQL/PostgreSQL)
| Method |
Description / Example |
where('col->key') |
User::where('options->lang', 'en') |
whereJsonContains() |
User::whereJsonContains('roles', 'admin') |
whereJsonLength() |
User::whereJsonLength('tags', '>', 3) |
Aggregates
| Method |
Description / Example |
count() |
User::where('active', true)->count() |
max($col) |
Order::max('total') |
min($col) |
Product::min('price') |
avg($col) |
Review::avg('rating') |
sum($col) |
Order::where('user_id', 1)->sum('total') |
exists() |
User::where('email', $email)->exists() |
doesntExist() |
Opposite of exists() |
Ordering
| Method |
Description / Example |
orderBy($col) |
User::orderBy('name') (asc default) |
orderBy($col, 'desc') |
User::orderBy('created_at', 'desc') |
orderByDesc($col) |
User::orderByDesc('created_at') |
latest($col?) |
Post::latest() (created_at desc) |
oldest($col?) |
Post::oldest() (created_at asc) |
inRandomOrder() |
User::inRandomOrder()->first() |
reorder() |
Remove existing orders, optionally add new |
Grouping & Having
| Method |
Description / Example |
groupBy($col) |
Order::groupBy('status')->selectRaw('status, count(*)') |
groupByRaw() |
->groupByRaw('YEAR(created_at)') |
having() |
->having('total', '>', 100) |
havingRaw() |
->havingRaw('SUM(amount) > ?', [1000]) |
Limiting & Offset
| Method |
Description / Example |
take($n) |
User::take(10)->get() |
limit($n) |
Alias for take() |
skip($n) |
User::skip(10)->take(5)->get() |
offset($n) |
Alias for skip() |
forPage($page, $perPage) |
User::forPage(2, 15)->get() |
Pagination
| Method |
Description / Example |
paginate($perPage) |
User::paginate(15) with page numbers |
simplePaginate() |
Only prev/next, no count query |
cursorPaginate() |
Cursor-based, best for large datasets |
Blade: {{ $users->links() }} | Append: $users->appends(['sort' => 'name'])
Selecting Columns
| Method |
Description / Example |
select($cols) |
User::select('id', 'name', 'email') |
select([...]) |
User::select(['id', 'name as username']) |
addSelect($col) |
Add to existing select |
selectRaw() |
->selectRaw('count(*) as count') |
distinct() |
Order::select('status')->distinct()->get() |
Raw Expressions
| Method |
Description / Example |
selectRaw() |
->selectRaw('price * ? as taxed', [1.1]) |
whereRaw() |
->whereRaw('LOWER(name) = ?', [$name]) |
orWhereRaw() |
Raw OR condition |
orderByRaw() |
->orderByRaw('FIELD(status, "pending", "active")') |
DB::raw() |
->select(DB::raw('COUNT(*) as count')) |
Security: Always use bindings (?) to prevent SQL injection.
Eager Loading (N+1 Prevention)
| Method |
Description / Example |
with($rel) |
Post::with('author')->get() |
with([$rels]) |
Post::with(['author', 'comments'])->get() |
with('rel.nested') |
Post::with('author.profile')->get() |
with(['rel' => fn]) |
Post::with(['comments' => fn($q) => $q->latest()]) |
without($rel) |
Remove eager load (on $with models) |
withOnly($rel) |
Override default $with on model |
Lazy Eager Loading
| Method |
Description / Example |
load($rel) |
$user->load('posts') after retrieval |
load(['rel' => fn]) |
$user->load(['posts' => fn($q) => $q->published()]) |
loadMissing() |
Only load if not already loaded |
Relationship Counts
| Method |
Description / Example |
withCount($rel) |
Post::withCount('comments') → comments_count |
withCount(['r' => fn]) |
->withCount(['comments' => fn($q) => $q->approved()]) |
withSum($rel, $col) |
Order::withSum('items', 'price') |
withAvg() |
Product::withAvg('reviews', 'rating') |
withMin() / withMax() |
Min/max aggregate on relation |
withExists($rel) |
User::withExists('subscription') → subscription_exists |
loadCount() |
Lazy load counts: $user->loadCount('posts') |
Querying Relationships
| Method |
Description / Example |
has($rel) |
Post::has('comments')->get() |
has($rel, $op, $n) |
Post::has('comments', '>=', 5)->get() |
doesntHave($rel) |
Post::doesntHave('comments')->get() |
whereHas($rel, fn) |
Post::whereHas('author', fn($q) => $q->where('active', 1)) |
orWhereHas() |
OR variant |
whereDoesntHave() |
User::whereDoesntHave('orders') |
whereRelation() |
Post::whereRelation('author', 'active', 1) |
MorphTo Relationships
| Method |
Description / Example |
whereHasMorph() |
Comment::whereHasMorph('commentable', [Post::class], fn($q) => ...) |
whereMorphedTo() |
Comment::whereMorphedTo('commentable', $post) |
morphWith() |
Activity::with(['subject' => fn($m) => $m->morphWith([Post::class => ['author']])]) |
Subquery Selects/Orders
| Method |
Description / Example |
addSelect() |
Subquery: ->addSelect(['last_order' => Order::select('created_at')->whereColumn('user_id', 'users.id')->latest()->limit(1)]) |
orderBy() |
Order by subquery: ->orderByDesc(Order::select('created_at')->whereColumn(...)) |
withAggregate() |
User::withAggregate('orders', 'max', 'total') |
Chunking (Memory Efficient)
| Method |
Description / Example |
chunk($n, fn) |
User::chunk(100, fn($users) => ...) |
chunkById($n, fn) |
Safe for updates: User::chunkById(100, fn($u) => ...) |
lazy($n) |
foreach (User::lazy(100) as $user) { } |
lazyById($n) |
Safe for updates during iteration |
cursor() |
Single query, yields one at a time |
Use: chunk/lazy for large datasets. cursor() for read-only iteration with minimal memory.
Conditional Clauses
| Method |
Description / Example |
when($cond, fn) |
->when($request->status, fn($q, $s) => $q->where('status', $s)) |
when($c, fn, fn) |
With else: ->when($sort, fn($q) => ..., fn($q) => $q->latest()) |
unless($cond, fn) |
Opposite of when() |
Tip: Perfect for optional filters: ->when($search, fn($q) => $q->where('name', 'like', "%$search%"))
Scopes
| Type |
Description / Example |
| Local scope |
public function scopeActive($q) { return $q->where('active', 1); } |
| Usage |
User::active()->get() |
| With params |
scopeOfType($q, $type) → User::ofType('admin') |
| Global scope |
Auto-applied to all queries (e.g., SoftDeletes) |
withoutGlobalScope() |
User::withoutGlobalScope(
ActiveScope::class
)
|
withoutGlobalScopes() |
Remove all or specific scopes |
Soft Deletes
| Method |
Description / Example |
withTrashed() |
User::withTrashed()->get() include deleted |
onlyTrashed() |
User::onlyTrashed()->get() only deleted |
withoutTrashed() |
Explicitly exclude (default behavior) |
trashed() |
$user->trashed() check if soft deleted |
Debugging
| Method |
Description / Example |
toSql() |
User::where(...)->toSql() returns SQL string |
toRawSql() |
SQL with bindings substituted (L10+) |
dd() |
User::where(...)->dd() dump and die |
dump() |
Dump query without dying |
getBindings() |
Get query bindings array |
Query Builder Methods
| Method |
Description / Example |
toBase() |
Get underlying query builder |
clone() |
Clone query for reuse |
tap(fn) |
->tap(fn($q) => Log::info($q->toSql())) |
pipe(fn) |
Transform query: ->pipe(fn($q) => $q->count()) |
Joins
| Method |
Example |
join() |
User::join('posts', 'users.id', '=', 'posts.user_id')->select('users.*', 'posts.title')->get() |
leftJoin() |
User::leftJoin('posts', 'users.id', '=', 'posts.user_id')->get() |
rightJoin() |
User::rightJoin('posts', 'users.id', '=', 'posts.user_id')->get() |
crossJoin() |
Size::crossJoin('colors')->get() |
joinSub() |
User::joinSub($latestPosts, 'latest_posts', fn($j) => $j->on('users.id', '=', 'latest_posts.user_id')) |
Prefer relationships: Use with() for eager loading instead of joins when possible. Joins return flat arrays, not models.
Collection Methods (After Retrieval)
| Method |
Description |
Example |
filter(fn) |
Filter items |
$users->filter(fn($u) => $u->active) |
map(fn) |
Transform each item |
$users->map(fn($u) => $u->name) |
pluck($key) |
Extract values |
$users->pluck('email') |
keyBy($key) |
Key by attribute |
$users->keyBy('id') |
groupBy($key) |
Group by attribute |
$users->groupBy('role') |
sortBy($key) |
Sort collection |
$users->sortBy('name') / sortByDesc() |
unique($key?) |
Remove duplicates |
$users->unique('email') |
contains(fn) |
Check if exists |
$users->contains(fn($u) => $u->admin) |
firstWhere() |
First matching |
$users->firstWhere('admin', true) |
sum($key) |
Sum values |
$orders->sum('total') |
Common Patterns
Optional filters: User::query()->when($request->role, fn($q, $r) => $q->where('role', $r))->when($request->search, fn($q, $s) => $q->where('name', 'like', "%$s%"))->paginate()
Get or create: User::firstOrCreate(['email' => $e], ['name' => $n]) | firstOrNew() doesn't save.
Update or create: User::updateOrCreate(['email' => $e], ['last_login' => now()])
Prevent N+1: Add protected $with = ['relation']; to model or use preventLazyLoading() in AppServiceProvider.
Fresh data: $user->fresh() re-fetches, $user->refresh() updates in place.