Что такое View Model
View Model — это класс, который отвечает за подготовку и формирование данных специально для представления (view) в Laravel. Он изолирует логику подготовки данных от контроллера и делает код чище и понятнее.
Проще говоря — это DTO, предназначенный не только для передачи данных, а именно для структурирования данных под потребности представления.
Проблема классического подхода
Обычно контроллеры Laravel выглядят так:
public function index()
{
$posts = Post::with('author')->where('published', true)->latest()->get();
$tags = Tag::popular()->get();
return view('blog.index', compact('posts', 'tags'));
}
Очень быстро код падает в «информационный беспорядок»:
- контроллер знает слишком много;
- данные тяжело переиспользовать;
- сложно управлять кешем;
- логика подготовки — разбросана.
Зачем нужен View Model
View Models помогают решить эти проблемы:
✅ контроллер становится тонким и понятным;
✅ представление не тянет лишнюю логику;
✅ данные собираются единой точкой;
✅ легко внедрять кеширование.
Первый View Model
Создадим класс View Model:
php artisan make:view-model BlogIndexViewModel
Пример реализации:
use Spatie\ViewModels\ViewModel;
class BlogIndexViewModel extends ViewModel
{
public function posts()
{
return Post::with('author')
->where('published', true)
->latest()
->take(10)
->get();
}
public function popularTags()
{
return Tag::popular()->take(10)->get();
}
public function seo(): array
{
return [
'title' => 'Блог',
'description' => 'Последние статьи'
];
}
}
Контроллер теперь выглядит так:
public function index()
{
return view('blog.index', new BlogIndexViewModel());
}
Laravel автоматически пробросит методы View Model в шаблон.
Использование во View
В шаблоне Blade вы теперь используете данные как обычные переменные:
<h1>{{ $seo['title'] }}</h1>
@foreach ($posts as $post)
<article>
<h2>{{ $post->title }}</h2>
<p>Автор: {{ $post->author->name }}</p>
</article>
@endforeach
Преимущества:
- код читаем;
- шаблон не «тянет» логику;
- меньше ошибок.
Добавляем кеширование
Кеширование — естественное место для View Model, ведь подготовка данных всё равно идёт в одном месте.
use Illuminate\Support\Facades\Cache;
public function posts()
{
return Cache::remember('blog.index.posts', now()->addMinutes(10), function () {
return Post::with('author')
->where('published', true)
->latest()
->take(10)
->get();
});
}
Теперь контроллер не знает вообще ничего о кешировании — это логически рядом с данными.
Когда использовать View Models
Используйте View Models, когда:
✔ одному view нужен сложный набор данных;
✔ логика подготовки данных растёт;
✔ нужны вычисляемые свойства;
✔ требуется удобная точка кеширования.
Когда View Models — не лучший выбор
❌ данные нужны только как JSON (лучше использовать API Resources);
❌ это бизнес-логика — её место в сервисных классах или репозиториях, а не в View Models.
Архитектурный бонус
View Models хорошо сочетаются с:
- сервисами (
Service Classes); - объектами запросов (
Query Objects); - классами действий (
Action Classes); - централизованным кешированием.
Это делает проект устойчивым к росту и понятным новым участникам команды.
Лучшие практики
Нужно только готовить данные, а не выполнять бизнес-логику.
Логику можно разделить по методам — это улучшает читаемость.
Именуйте методы так, чтобы их было удобно использовать в шаблонах.
Кеш должен быть привязан к данным, а не к контроллеру.
Если View Model становится слишком громоздкой — возможно, пора вынести часть логики в сервисы.
Заключение
View Models — это не просто удобный инструмент Laravel, а принцип архитектурного разделения ответственности, который помогает:
✔ уменьшить связность кода;
✔ сделать контроллеры простыми;
✔ оптимизировать кеширование;
✔ улучшить поддержку шаблонов.