Skip to content

Latest commit

 

History

History
109 lines (81 loc) · 3.6 KB

Collections.md

File metadata and controls

109 lines (81 loc) · 3.6 KB

Collections

⬆️ Go to top ⬅️ Previous (Validation) ➡️ Next (Auth)

  1. Don’t Filter by NULL in Collections
  2. Use groupBy on Collections with Custom Callback Function
  3. Multiple Collection Methods in a Row
  4. Calculate Sum with Pagination
  5. Serial no. in foreach loop with pagination
  6. Higher order collection methods
  7. Higher order collection message

Don’t Filter by NULL in Collections

You can filter by NULL in Eloquent, but if you're filtering the collection further - filter by empty string, there's no "null" in that field anymore.

// This works
$messages = Message::where('read_at is null')->get();

// Won’t work - will return 0 messages
$messages = Message::all();
$unread_messages = $messages->where('read_at is null')->count();

// Will work
$unread_messages = $messages->where('read_at', '')->count();

Use groupBy on Collections with Custom Callback Function

If you want to group result by some condition which isn’t a direct column in your database, you can do that by providing a closure function.

For example, if you want to group users by day of registration, here’s the code:

$users = User::all()->groupBy(function($item) {
    return $item->created_at->format('Y-m-d');
});

⚠️ Notice: it is done on a Collection class, so performed AFTER the results are fetched from the database.

Multiple Collection Methods in a Row

If you query all results with ->all() or ->get(), you may then perform various Collection operations on the same result, it won’t query database every time.

$users = User::all();
echo 'Max ID: ' . $users->max('id');
echo 'Average age: ' . $users->avg('age');
echo 'Total budget: ' . $users->sum('budget');

Calculate Sum with Pagination

How to calculate the sum of all records when you have only the PAGINATED collection? Do the calculation BEFORE the pagination, but from the same query.

// How to get sum of post_views with pagination?
$posts = Post::paginate(10);
// This will be only for page 1, not ALL posts
$sum = $posts->sum('post_views');

// Do this with Query Builder
$query = Post::query();
// Calculate sum
$sum = $query->sum('post_views');
// And then do the pagination from the same query
$posts = $query->paginate(10);

Serial no in foreach loop with pagination

We can use foreach collection items index as serial no (SL) in pagination.

   ...
   <th>Serial</th>
    ...
    @foreach ($products as $product)
    <tr>
        <td>{{ $loop->index + $product->firstItem() }}</td>
        ...
    @endforeach

it will solve the issue of next pages(?page=2&...) index count from continue.

Higher order collection message

Collections also provide support for "higher order messages", which are short-cuts for performing common actions on collections. This example calculates the price per group of products on an offer.

$offer = [
        'name'  => 'offer1',
        'lines' => [
            ['group' => 1, 'price' => 10],
            ['group' => 1, 'price' => 20],
            ['group' => 2, 'price' => 30],
            ['group' => 2, 'price' => 40],
            ['group' => 3, 'price' => 50],
            ['group' => 3, 'price' => 60]
        ]
];
                
$totalPerGroup = collect($offer['lines'])->groupBy->group->map->sum('price');