kencol
kencol

Reputation: 57

Laravel Eloquent collect paired items

I'm looking for a way to aggregate a collection of eloquent users pairs in Laravel. [[user][partner]]

I've got the following users table structure

[id] [name] [partner_id]

A user entity has matching partner_ids or null (if no partner exists)

| id | name          | partner_id |
+----+---------------+------------+
| 1  | John Doe      | 3          |
| 2  | J Random User | NULL       |
| 3  | Jane Doe      | 1          |
| .. | ...           | ...        |

Expected result:

[
  [
    { "id": 1, "name": "John Doe", "partner_id": 3 },
    { "id": 3, "name": "Jane Doe", "partner_id": 1 },
  ],
  [
    { "id": 2, "name": "J Random User", "partner_id": null },
  ]
]

I don't get how I fetch the users once and aggregate the $users-collection into pairs in my controller.

<?php

namespace App\Http\Controllers;

use App\User;

class PairController extends Controller
{
    public function index()
    {
        $users = User::all();
        $collection = collect();

        foreach ($users as $user) {
            $myself = $user->id;
            $partner = $user->partner_id;

            // ... ???
        }

        return $collection->unique();
    }
}

Can anyone help me out with a solution? I'm stuck in my brain.

Upvotes: 2

Views: 68

Answers (2)

Spholt
Spholt

Reputation: 4012

Try this, it's not perfect but it may be a place to start.

// Return all users and group them by their id
$grouped_users = User::all()->groupBy('id');

// Now loop through each user on record
User::all()->each(function ($user) use (&$grouped_users) {
    if ($user->partner_id && $grouped_users->has($user->partner_id)) {
        $partner_id = $user->partner_id;

        // Push the user model into our grouped collection
        $grouped_users[$partner_id]->push($user);

        // Remove the id for the current user from the collection
        $grouped_users->forget($user->id);
    }
});

Upvotes: 1

Renny M. Roy
Renny M. Roy

Reputation: 178

Try the code below.

    public function index()
    {
        $usersWithoutPartner = collect();
        $usersWithPartner = collect();
        User::chunk(100, function ($users) use ($usersWithoutPartner, $usersWithPartner) {
            foreach ($users as $user) {
                if ($user->partner_id == null) {
                    $usersWithoutPartner->push($user);
                } else {
                    $usersWithPartner->push($user);
                }
            }
        });

        $finalCollection = collect();
        $finalCollection->push($usersWithoutPartner);
        $finalCollection->push($usersWithPartner);
        return $finalCollection;
}

Upvotes: 2

Related Questions