Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Події
Інше
Про нас
Tips 12 серпня 2026

withDefault() - ніяких null при зв'язках

Постійно перевіряєте, чи існує зв'язок, перед доступом до нього?

withDefault() повертає "порожню" модель замість null.

Переваги:

  • Менше if ($user->profile)
  • Чистіші Blade-шаблони
  • Можливість задати дефолтні значення
4
// User model
public function profile()
{
  return $this->hasOne(Profile::class)
    ->withDefault([
      'bio' => 'No bio provided',
      'avatar' => 'default.png',
      'website' => null,
    ]);
}

// Без перевірок на null
{{ $user->profile->bio }}
// Динамічні дефолти
public function profile()
{
  return $this->hasOne(Profile::class)
    ->withDefault(function ($profile, $user) {
      $profile->bio = "Member since {$user->created_at->year}";
    });
}

// BelongsTo з дефолтом
public function author()
{
  return $this->belongsTo(User::class, 'author_id')
    ->withDefault([
      'name' => 'Guest',
      'email' => 'noreply@example.com',
    ]);
}

// У Blade
{{ $post->author->name }} // Ніколи не null

Читати в документації

Коментарі

Увійдіть, щоб залишити коментар

Будьте першим, хто залишить коментар!

Інші поради

Tips 28 серпня 2026

pipe() - кастомна логіка у ланцюжку

Потрібно застосувати складну логіку до всієї колекції?

pipe() передає в callback усю колекцію і повертає те, що callback повернув.

Переваги:

  • Гнучка логіка
  • Розбиття складних ланцюжків
  • Умовні трансформації
  • Дебаг

Різниця з map():

  • map() - елемент за елементом
  • pipe() - вся колекція одразу

Порада: використовувати іменовані функції для читабельності.

$result = $users
  ->where('active', true)
  ->pipe(fn($c) => $c->sortBy('last_login')->take(10))
  ->values();

// Умовне сортування
$posts = Post::all()->pipe(function ($posts) use ($request) {
  return $request->sort === 'popular'
    ? $posts->sortByDesc('views')
    : $posts->sortByDesc('created_at');
});

// Дебаг
$result = $users
  ->where('active', true)
  ->pipe(fn($c) => tap($c, fn($c) => logger($c->count())))
  ->where('role', 'admin');
Tips 26 серпня 2026

partition() - поділ колекції на дві частини

Потрібно поділити користувачів на активних і неактивних?

partition() повертає одразу дві групи.

Різниця з filter():

  • filter() повертає лише truthy
  • partition() повертає truthy і falsy одразу

Сценарії:

  • Валідні / невалідні дані
  • Passed / failed
  • Approved / pending

Порада: зручно для різних обробок двох груп.

4
[$active, $inactive] = $users->partition(fn($u) => $u->active);

// Дві різні обробки
$active->each(fn($u) => ...);
$inactive->each(fn($u) => ...);

// Валідація
[$valid, $invalid] = $orders->partition(fn($o) =>
  $o->total > 0 && $o->email !== null
);

// Студенти
[$passed, $failed] = $students->partition(
  fn($s) => $s->score >= 60
);
Tips 24 серпня 2026

groupBy() - організація даних як у таблиці

Потрібно показати пости за категоріями? Вкладені цикли не потрібні.

groupBy() групує колекцію за ключем.

Як працює:

Повертає масив груп, де кожна група - окрема колекція.

Розширені можливості:

  • Групування за callback
  • Кілька рівнів групування
  • Dot notation

Порада: ідеально для аналітики, звітів і категоризації.

// Групування за категорією
$byCategory = $posts->groupBy('category_id');

// Групування за роком
$byYear = $posts->groupBy(fn($p) => $p->created_at->year);

// Доступ до груп
foreach ($byCategory as $categoryId => $posts) {
  echo "Category {$categoryId}: {$posts->count()} posts\n";
}

// Кілька рівнів
$byYearMonth = $posts->groupBy([
  fn($p) => $p->created_at->year,
  fn($p) => $p->created_at->month,
]);

// Групування по зв'язку
$byPostTitle = $comments->groupBy('post.title');

// Практичний приклад - суми продажів
$report = $orders->groupBy('status')
  ->map(fn($group) => $group->sum('total'));
Tips 21 серпня 2026

filter() vs reject() - очищення даних

Потрібно прибрати частину елементів? Писати складні if не обов'язково.

filter() залишає елементи, що відповідають умові. reject() прибирає елементи, що відповідають умові.

Різниця:

  • filter() - залишає truthy
  • reject() - прибирає truthy
  • Обидва повертають нову колекцію

Розширено:

Для простих порівнянь краще where(), whereIn(), whereBetween().

Порада: filter() без callback прибирає всі falsy (null, false, 0, '', []).

// filter() - тільки активні
$active = $users->filter(fn($u) => $u->active === true);

// reject() - видалити неактивних
$active = $users->reject(fn($u) => $u->active === false);

// filter() без callback
$values = collect([1, 2, null, 3, false, '', 4]);
$cleaned = $values->filter();
// [1, 2, 3, 4]

// where()
$admins = $users->where('role', 'admin');
$verified = $users->where('email_verified_at', '!=', null);

// whereIn()
$staff = $users->whereIn('role', ['admin', 'moderator']);

// whereBetween()
$recent = $posts->whereBetween('created_at', [
  now()->subDays(7),
  now()
]);

// Комбінування фільтрів
$result = $users
  ->where('active', true)
  ->whereIn('role', ['admin', 'editor'])
  ->filter(fn($u) => $u->posts_count > 10);
Tips 19 серпня 2026

chunk() - поділ даних на частини

Потрібно обробити 10 000 елементів? Або API обмежує 100 запитів за хвилину?

chunk() розбиває колекцію на менші групи.

Сценарії:

  • Обмеження API
  • Пакетна обробка
  • Керування пам'яттю
  • Прогрес-бар

Відмінність від query chunk():

Collection chunk() працює з уже завантаженими даними. Query chunk() завантажує дані з бази порціями.

Порада: поєднувати з sleep() для API rate limit.

// Поділ на частини по 100
$users = User::all();
$users->chunk(100)->each(function ($batch) {
  $this->sendBatchEmail($batch);
});

// API rate limit
$products = collect($apiProducts);
$products->chunk(50)->each(function ($batch) {
  $this->syncToDatabase($batch);
  sleep(1);
});

// Прогрес
$done = 0;

$users->chunk(100)->each(function ($batch) use (&$done) {
  $batch->each(fn($u) => $this->process($u));
  $done += $batch->count();
  echo "Progress: {$done}\n";
});

// Комбінування з іншими методами
$users->chunk(100)->map(function ($chunk) {
  return $chunk->pluck('email');
});
Завантаження...