Laravel View Models: Simplifying Data for Your Views
In Laravel, the View Models pattern is a powerful tool to simplify data handling between your controllers and views. Instead of passing complex data structures directly from controllers, a View Model acts as an intermediary to prepare the data in a way that’s easy for your views to consume.
Laravel View Models: Simplifying Data for Your Views
In Laravel, the View Models pattern is a powerful tool to simplify data handling between your controllers and views. Instead of passing complex data structures directly from controllers, a View Model acts as an intermediary to prepare the data in a way that’s easy for your views to consume.
What is a View Model?
A View Model is a dedicated class responsible for encapsulating the data needed for a particular view. It ensures that your views only deal with the necessary information and simplifies complex data into a format that’s easier to work with.
Why Use View Models?
- Separation of Concerns: By moving data preparation logic from controllers to a View Model, you keep controllers clean and focused on handling requests.
- Reusability: You can reuse the same View Model across multiple views if they share similar data structures.
- Testability: Isolating view-related logic into its own class makes it easier to test and maintain.
How to Implement View Models in Laravel
Here’s how to create and use a View Model in a Laravel project:
Create the View Model: You can create a new class for your View Model. For example, for a product list page:
php artisan make:class ProductListViewModel
Add Data to the View Model: In this class, define the data you want to pass to the view:
namespace App\ViewModels;
use App\Models\Product;
class ProductListViewModel
{
public function products()
{
return Product::all()->map(function ($product) {
return [
'name' => $product->name,
'price' => $product->price,
'description' => $product->description,
];
});
}
}
This class fetches products and prepares a simplified array of the product data.
Pass the View Model to the View: In your controller, instead of passing raw data, instantiate the View Model and pass it to the view:
namespace App\Http\Controllers;
use App\ViewModels\ProductListViewModel;
class ProductController extends Controller
{
public function index()
{
$viewModel = new ProductListViewModel();
return view('products.index', [
'viewModel' => $viewModel,
]);
}
}
Use the View Model in the Blade Template: In your Blade view, you can now access the prepared data using the View Model:
@foreach($viewModel->products() as $product)
<div>
<h3>{{ $product['name'] }}</h3>
<p>{{ $product['price'] }}</p>
<p>{{ $product['description'] }}</p>
</div>
@endforeach
Example: Refactoring a Blog Post List
Let’s say you have a blog with posts, and you need to display a list of blog posts on the homepage. Instead of directly passing the posts from the controller to the view, use a View Model to prepare the data.
BlogPostViewModel:
namespace App\ViewModels;
use App\Models\Post;
class BlogPostViewModel
{
public function posts()
{
return Post::latest()->take(5)->get()->map(function ($post) {
return [
'title' => $post->title,
'excerpt' => substr($post->content, 0, 100),
'author' => $post->author->name,
'created_at' => $post->created_at->toFormattedDateString(),
];
});
}
}
Controller:
namespace App\Http\Controllers;
use App\ViewModels\BlogPostViewModel;
class BlogController extends Controller
{
public function index()
{
$viewModel = new BlogPostViewModel();
return view('blog.index', ['viewModel' => $viewModel]);
}
}
Blade View:
@foreach($viewModel->posts() as $post)
<div>
<h2>{{ $post['title'] }}</h2>
<p>{{ $post['excerpt'] }}</p>
<p>Written by {{ $post['author'] }} on {{ $post['created_at'] }}</p>
</div>
@endforeach
Conclusion
View Models offer a clean and organized way to handle the data your views need. By moving data preparation logic out of your controllers, you maintain better separation of concerns and keep your code more maintainable. This approach is especially useful for complex data handling and can be a great tool for enhancing your Laravel application’s architecture.
Book a session with me: https://adplist.org/mentors/mohasin-hossain