Home > Blockchain >  Eloquent - Reduce the data from an Eager Loaded Relationsip with Resources
Eloquent - Reduce the data from an Eager Loaded Relationsip with Resources

Time:05-30

I have a database of List of Users in a Group and I'm using eager loading to load those Users as long as the current active users have the ability to view them.

$grouplist = GroupList::with('groups.listOfUsersInGroup.userInfo')
    ->where('user_id', auth()->user()->id)
    ->get();

With that I get a complicated response like shown below

[
    {
        "id": 2,
        "group_id": "1",
        "user_id": "1",
        "groups": [
            {
                "id": 1,
                "name": "Group 1",
                "list_of_users_in_group": [
                    {
                        "id": 1,
                        "group_id": "1",
                        "user_id": "1",
                        "user_info": {
                            "fullname": "User 1",
                            "uid": "001"
                        }
                    },
                    {
                        "id": 9,
                        "group_id": "1",
                        "user_id": "2",
                        "user_info": {
                            "fullname": "User 2",
                            "uid": "002"
                        }
                    },
                    {
                        "id": 10,
                        "group_id": "1",
                        "user_id": "5",
                        "user_info": {
                            "fullname": "User 3",
                            "uid": "003"
                        }
                    }
                ]
            }
        ]
    },
    {
        "id": 13,
        "group_id": "2",
        "user_id": "1",
        "groups": [
            {
                "id": 1,
                "name": "Group 1",
                "list_of_users_in_group": [
                    {
                        "id": 1,
                        "group_id": "2",
                        "user_id": "1",
                        "user_info": {
                            "fullname": "User 1",
                            "uid": "001"
                        }
                    },
                    {
                        "id": 9,
                        "group_id": "2",
                        "user_id": "4",
                        "user_info": {
                            "fullname": "User 4",
                            "uid": "004"
                        }
                    }
                ]
            }
        ]
    }
]

I would like to simplify it and achieve a much cleaner look while removing duplicate entries

[
    {
        "fullname": "User 1",
        "uid": "001"
    },
    {
        "fullname": "User 2",
        "uid": "002"
    },
    {
        "fullname": "User 3",
        "uid": "003"
    },
    {
        "fullname": "User 4",
        "uid": "004"
    }
]

With a little bit of foreach trickery I can get something like that:

$users = [];

$count = 0;

foreach ($grouplist as $collectionOfGroupLIst) {
    // $count  ;
    foreach ($collectionOfGroupLIst->groups as $listOfGroups) {
        foreach ($listOfGroups->listOfUsersInGroup as $listOfUsers) {
            $users[$count] = $listOfUsers->userInfo;

            $count  ;
        }
    }
}

return array_unique($users, SORT_REGULAR);

Now the question is it possible to get the same result with Resources or is there a much cleaner way of achieving my goal? As much as this code will work as the application is for a small amount of users and User Groups. It will become a problem with larger Users and User Groups.

CodePudding user response:

You could try to get only the data required. And then use Laravel Collection's (magic) methods to format as per your requirement.

$groupList = GroupList::with([
    'groups:id',
    'groups.list_of_users_in_group:id,group_id,user_id',
    'groups.list_of_users_in_group.user_info',
])
->where('user_id', auth()->id())
->select('id', 'group_id')
->get()
->pluck('groups')
->flatten(1)
->pluck('list_of_users_in_group')
->flatten(1)
->pluck('user_info')
->unique();

By fetching only the required data via queries will be a performance optimisation. However for larger databases fetching all data at once could be a severe performance hit and may require pagination.

Laravel Docs - Collection - Available Methods

Laravel Docs - Eager loading specific columns

  • Related