Tryst with Laravel – Collections as substitute for Eloquent fetch
Tushar Bohra
January 12, 2018

Laravel offers the Illuminate\Support\Collections as an ultimate powerful tool to work with arrays. Also the results of all Illuminate\Database\Eloquent queries are the instance of the Collection class. This makes collections a very important component of the Laravel ecosystem. I have couple of times performed operations in Collections which were too complicated to be done via Eloquent alone.

 

I find collections very useful in creating reports. Specially in cases where we need to represent the same data in different presentations. Collections have two very neat tricks up their sleeves which make them extreme competent for this. All collections are immutable. When we run couple of collections methods on a collection, it returns a new instance of that collection. This leaves the original collection unaffected which can be used for other operations.

 

Lets consider an example of an ice-cream shop. They have a dashboard that shows all the orders in two tables. One is sorted based on the flavours of the ice-cream and the other one is sorted via the calorie value. Here we’ll have an Order model, that stores information about the order like its value, customer info, who served it, etc. Its is related to the IceCream model via a many-to-one relationship. All information with regards to the flavours, calorie value etc. is stored in the IceCream model.

 

Now for our dashboard, we can do two fetch from the Order model for the tables or we can use collections.

 

$orders = Order::with('iceCream')->all();

$flavour_sorted = $orders->sortBy(function ($order) {
                      return $order->iceCream->flavour;
                  });

$calorie_sorted = $orders->sortBy(function ($order) {
                      return $order->iceCream->calorie;
                  });

 

Now imagine the ice-cream shop is celebrating a health week and wants to just show the orders that are below a calorie count in its dashboard. In this we can make use of another awesome collection property called chaining. This allows us to chain multiple collection methods fluently to get the final result. Here, we’ll use the results from the same single fetch operation and chain a filter method to the sort method.

 

$orders = Order::with('iceCream')->all();

$flavour_sorted = $orders->filter(function ($order, $key) {
                      return $order->iceCream->calorie < 200;
                  })->sortBy(function ($order) {
                      return $order->iceCream->flavour;
                  });

$calorie_sorted = $orders->filter(function ($value, $key) {
                      return $order->iceCream->calorie < 200;
                  })->sortBy(function ($order) {
                      return $order->iceCream->calorie;
                  });

 

There are many other awesome operations that we can do with Collections. We can extend these functions, add more complex operation for filtering and sorting inside the callback functions and it works just fine.