Laracode
Laracode

Проверка отсутствия модели

При написании тестов мы часто используем assertDatabaseMissing, чтобы проверить, была ли модель удалена. Знали ли вы, что в Laravel есть удобный хелпер assertModelMissing, который делает то же самое, но проще?

<?php

use App\Models\User;

$user = User::factory()->create();

$user->delete();

// Вместо этого 🥱
$this->assertDatabaseMissing('users', [
    'email' => $user->email
]);

// Можно сделать так 😎
$this->assertModelMissing($user);

Eloquent метод “upsert”

Иногда вам может понадобиться обновить несколько записей или создать их, если они не существуют. В Laravel для этого есть удобный метод upsert.

<?php

// Этот код обновит цену всех записей, 
// соответствующих указанным departure и destination, 
// или создаст их, если они не существуют.

Flight::query()->upsert([
    ['departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99],
    ['departure' => 'Chicago', 'destination' => 'New York', 'price' => 150]
], uniqueBy: ['departure', 'destination'], update: ['price']);

Повторное использование существующих моделей

При создании фабрик вы можете использовать одну и ту же модель для всех связей вместо создания новой модели для каждой. В Laravel для этого есть удобный метод recycle.

<?php

$airlines = Airline::factory()->count(3)->create();

// Для 100 билетов будут использоваться только 3 авиакомпании
Ticket::factory()
    ->count(100)
    ->recycle($airlines) // Вы также можете передать только одну модель
    ->create();

Доступ к переменной $loop родительского цикла

Иногда при работе с вложенными циклами может потребоваться отслеживать итерацию родительского цикла. Blade упрощает эту задачу, предоставляя доступ к переменной родительского цикла.

@foreach ($users as $user)
    @foreach ($user->posts as $post)
        @if ($loop->parent->first)
            // Это первая итерация родительского цикла.
        @endif
    @endforeach
@endforeach

Читаемые для человека даты

Хотели ли вы когда-нибудь отображать даты в формате, понятном человеку, вместо точных значений? Например, "1 день назад" или "месяц назад"? В Carbon для этого существует метод diffForHumans.

<?php

// 5 days ago
$post->created_at->diffForHumans();

// 5 days 23 minutes ago
$post->created_at->diffForHumans(['parts' => 2]);

// 5 days 24 minutes 36 seconds ago
$post->created_at->diffForHumans(['parts' => 3]);

Более читаемые числа

Когда вы работаете с числами, чем они длиннее, тем сложнее их читать. Знали ли вы, что можно использовать подчёркивания для повышения читаемости?

<?php

$amount = 1000;
$amount = 1_000;

$amount = 100000;
$amount = 100_000;

$amount = 100000000;
$amount = 100_000_000;

Добавление фрагмента в URL

Знали ли вы, что в Laravel есть метод withFragment, который позволяет добавить фрагмент в URI при редиректе?

<?php

return redirect()
    ->back()
    ->withFragment('testimonials');    
// exmaple.ru/#testimonials

return redirect()
    ->route('product.show')
    ->withFragment('reviews');    
// exmaple.ru/product/1#reviews

Методы коллекции dot и undot

При работе с коллекциями в Laravel вам может понадобиться преобразовать многомерную коллекцию в одноуровневую или наоборот. Для этого существуют два удобных метода: dot и undot.

<?php

$collection = collect(['products' => ['desk' => ['price' => 100]]]);

$dotted = $collection->dot();    
// ['products.desk.price' => 100]

$undotted = $collection->undot(); 
// ['products' => ['desk' => ['price' => 100]]]

Проверка изменения значения ключа модели

Иногда необходимо проверить, было ли значение указанного ключа модели изменено. В Laravel для этого есть метод originalIsEquivalent(), который делает эту задачу простой и удобной 🚀

<?php

// ['name' => 'old']
$user = User::firstOrFail();

$user->name = 'old'; 

// Значение осталось прежним
$user->originalIsEquivalent('name'); // true

$user->name = 'new'; 

// Значение изменилось
$user->originalIsEquivalent('name'); // false