44 lines
1.3 KiB
Markdown
44 lines
1.3 KiB
Markdown
# Collection Best Practices
|
|
|
|
## Use Higher-Order Messages for Simple Operations
|
|
|
|
Incorrect:
|
|
```php
|
|
$users->each(function (User $user) {
|
|
$user->markAsVip();
|
|
});
|
|
```
|
|
|
|
Correct: `$users->each->markAsVip();`
|
|
|
|
Works with `each`, `map`, `sum`, `filter`, `reject`, `contains`, etc.
|
|
|
|
## Choose `cursor()` vs. `lazy()` Correctly
|
|
|
|
- `cursor()` — one model in memory, but cannot eager-load relationships (N+1 risk).
|
|
- `lazy()` — chunked pagination returning a flat LazyCollection, supports eager loading.
|
|
|
|
Incorrect: `User::with('roles')->cursor()` — eager loading silently ignored.
|
|
|
|
Correct: `User::with('roles')->lazy()` for relationship access; `User::cursor()` for attribute-only work.
|
|
|
|
## Use `lazyById()` When Updating Records While Iterating
|
|
|
|
`lazy()` uses offset pagination — updating records during iteration can skip or double-process. `lazyById()` uses `id > last_id`, safe against mutation.
|
|
|
|
## Use `toQuery()` for Bulk Operations on Collections
|
|
|
|
Avoids manual `whereIn` construction.
|
|
|
|
Incorrect: `User::whereIn('id', $users->pluck('id'))->update([...]);`
|
|
|
|
Correct: `$users->toQuery()->update([...]);`
|
|
|
|
## Use `#[CollectedBy]` for Custom Collection Classes
|
|
|
|
More declarative than overriding `newCollection()`.
|
|
|
|
```php
|
|
#[CollectedBy(UserCollection::class)]
|
|
class User extends Model {}
|
|
``` |