Перетворення JSON у типізовані колекції за допомогою AsCollection::of() у Laravel

Перекладено ШІ
Оригінал: Laravel News
Оновлено: 20 травня, 2025
В Laravel метод AsCollection::of() спрощує роботу з даними, автоматично перетворюючи JSON-колонки на строго типізовані колекції об'єктів значень. Досліджуйте, як ця можливість може покращити структуру вашого коду та спростити обслуговування складних даних, прочитавши статтю!

Laravel покращує обробку даних завдяки методу AsCollection::of(), що дозволяє розробникам автоматично перетворювати JSON-колонки в колекції об'єктів певного типу. Ця функція надає структурованість і легкість підтримки у складних сценаріях зберігання даних.

Працюючи зі складними структурами даних у Laravel, часто виникає необхідність зберігати інформацію в JSON-колонках, але використання сирих масивів може призвести до труднопідтримуваного коду. Метод AsCollection::of() вирішує цю проблему, перетворюючи JSON-дані на коректно типізовані колекції:

use App\ValueObjects\Setting;
use Illuminate\Database\Eloquent\Casts\AsCollection;

protected function casts(): array
{
    return [
        'settings' => AsCollection::of(Setting::class)
    ];
}

Таке приведення типів автоматично перетворює вашу JSON-колонку в колекцію екземплярів вказаного класу, еквівалентну:

Collection::make($this->attributes['settings'])->mapInto(Setting::class);

Перетворення відбувається автоматично при зчитуванні моделі з бази даних, забезпечуючи безпеку типів і інкапсуляцію без додаткових зусиль.

Розгляньте створення системи управління контентом, де у статей є декілька налаштувань конфігурації. Кожне налаштування містить ключ, значення і прапорець видимості:

namespace App\ValueObjects;

use Illuminate\Contracts\Support\Arrayable;
use JsonSerializable;

class ArticleSetting implements Arrayable, JsonSerializable
{
    public function __construct(
        public readonly string $key,
        public readonly string $value,
        public readonly bool $isPublic = false
    ) {}

    public function toArray()
    {
        return [
            'key' => $this->key,
            'value' => $this->value,
            'is_public' => $this->isPublic,
        ];
    }

    public function jsonSerialize(): mixed
    {
        return $this->toArray();
    }

    public function isVisibleToGuests(): bool
    {
        return $this->isPublic && !empty($this->value);
    }
}

У вашій моделі Article застосуйте кастинг AsCollection::of():

namespace App\Models;

use App\ValueObjects\ArticleSetting;
use Illuminate\Database\Eloquent\Casts\AsCollection;
use Illuminate\Database\Eloquent\Model;

class Article extends Model
{
    protected function casts(): array
    {
        return [
            'settings' => AsCollection::of(ArticleSetting::class)
        ];
    }

    public function getPublicSettingsAttribute()
    {
        return $this->settings->filter(fn ($setting) => $setting->isPublic);
    }
}

Тепер можна працювати з налаштуваннями статей як з об'єктами першого класу:

$article = Article::find(1);

// Отримати всі налаштування як об'єкти ArticleSetting
$allSettings = $article->settings;

// Фільтруйте за методами вашого об'єкта значення
$visibleSettings = $article->settings->filter(fn ($setting) => $setting->isVisibleToGuests());

// Додати нове налаштування (автоматично серіалізується назад у JSON)
$article->settings->push(new ArticleSetting('author_display', 'John Doe', true));
$article->save();

Цей підхід особливо ефективний для таких завдань, як налаштування користувачів, конфігурації додатків, відповіді на опитування, активація функцій з метаданими або будь-яка ситуація, що потребує структурованих даних з узгодженими шаблонами