1. Set Default Attribute Values in Models
class Post extends Model {
protected $attributes = [
'status' => 'pending',
];
}Why it matters:
- Cleaner code
- Prevents missing defaults
- Centralized logic
2. Optimize Queries with whereIntegerInRaw()
User::whereIntegerInRaw('id', [1,2,3,4,5])->get();Why it's better:
- Faster for large datasets
- Avoids type casting issues
3. Use withAggregate() for Efficient Subqueries
$post = Post::withAggregate('user', 'name')->first();
$post->user_name;Benefit:
- Reduces memory usage
- Avoids N+1 queries
4. Handle SQL Errors Gracefully
try {
// your query
} catch (\Illuminate\Database\QueryException $e) {
if ($e->getCode() == '23000') {
return back()->withErrors('Invalid data');
}
}Use case:
- Handle duplicate entries
- Catch constraint violations
5. Perform Actions with firstOr()
User::where('email', $email)->firstOr(function () {
// fallback logic
});Why it’s useful:
- Cleaner alternative to condition checks
- Keeps logic inline
6. Process Large Data with chunkMap()
return User::orderBy('name')
->chunkMap(fn ($user) => [
'id' => $user->id,
'email' => $user->email,
], 25);Benefit:
- Efficient memory usage
- Cleaner than manual chunk loops
7. Ensure Single Record with sole()
$user = User::where('email', $email)->sole();Behavior:
- Throws exception if 0 or multiple records found
8. Human-Readable Dates with diffForHumans()
$post = Post::first();
$post->created_at->diffForHumans();Example output:
- 1 minute ago
- 2 months ago
9. Compare Relationships with is()
$post->author()->is($user);Why:
- Cleaner and more expressive
- Works safely with relationships
10. Advanced Pivot Relationships
// User model
public function roles() {
return $this->belongsToMany(Role::class)
->using(RoleUser::class)
->withPivot(['team_id']);
}class RoleUser extends Pivot {
public function team() {
return $this->belongsTo(Team::class);
}
}$teamName = auth()->user()
->roles()
->first()
->pivot
->team
->name;Why this is powerful:
- Treat pivot as a real model
- Add relationships inside pivot