Laravel Eloquent: How to merge multiple collections

Updated: January 17, 2024 By: Guest Contributor Post a comment

Introduction

Laravel, a popular PHP web application framework, is known for its eloquent ORM that provides a beautiful, simple ActiveRecord implementation for working with databases. Within Eloquent, a common task developers may encounter is dealing with collections of models. In this tutorial, we will explore how to merge multiple Eloquent collections. We’ll begin with the basics and progressively cover more advanced scenarios, complete with examples and expected outputs.

Merging Eloquent Collections

Eloquent collections are instances of the Illuminate\Support\Collection class and are returned when you use methods like get or all on a model query. Collections provide a variety of helpful methods for iterating, mapping, reducing, and more.

Simple Merge

To combine two collections, you can use the merge method:

$firstCollection = User::where('status', 'active')->get();
$secondCollection = User::where('status', 'inactive')->get();

$mergedCollection = $firstCollection->merge($secondCollection);

Output for the merged collection will simply combine both sets without removing duplicate models containing same ID:

Collection {#1 [
    // Combined models from both collections
]}

Remove Duplicates After Merge

If you need to remove duplicates after the merge, use the unique method:

$uniqueCollection = $mergedCollection->unique('id');

The result is a collection with unique models based on their ‘id’ attribute:

Collection {#2 [
    // Unique models based on ID
]}

Advanced Merge Operations

What if you’re working with different types of models? You can still merge collections:

$userCollection = User::where('status', 'active')->get();
$postCollection = Post::all();

$mergedDifferentCollections = $userCollection->merge($postCollection);

The result is a collection containing both User and Post instances.

Merging Collections with Relations

Sometimes, you might want to merge collections of related models:

// Assume users have 'posts' relationship returning a hasMany relation
$user = User::with('posts')->find(1);
$additionalPosts = Post::where('status', 'published')->get();

$mergedPosts = $user->posts->merge($additionalPosts);

This would produce a merged collection with the user’s posts alongside any additional ‘published’ posts.

Conditional Merging

You may only want to merge collections under certain conditions. Conditional merging is just as straightforward:

$collectionOne = User::all();
$collectionTwo = User::where('score', '>', 100)->get();

$mergedWithCondition = $collectionOne->when($condition, function ($collection) use ($collectionTwo) {
    return $collection->merge($collectionTwo);
});

If $condition is true, the two collections will merge; otherwise, $collectionOne remains unchanged.

Wrapping up

As seen in the examples above, merging collections in Laravel Eloquent is both versatile and straightforward. Whether you’re working with simple collections, dealing with duplicates, combining different model types, merging relations, or conditional merges, Eloquent provides you with the tools you need. Just remember the fundamental Eloquent collection methods: merge, unique, and, for conditional logic, when.

In brief, understanding how to adeptly manipulate and merge Eloquent collections can significantly streamline data handling in your Laravel applications. The underlying simplicity and power of these operations allow for elegant and efficient code organization and execution.