Laravel:使用 unset() 后无法在急切加载中重新索引集合的数组

Posted

技术标签:

【中文标题】Laravel:使用 unset() 后无法在急切加载中重新索引集合的数组【英文标题】:Laravel: Cannot reindex collection's array in eager loading after using unset() 【发布时间】:2021-06-14 20:38:54 【问题描述】:

我有以下代码:

// User.php
public function groups() 
    return $this->belongsToMany(
        Group::class,
        'group_user',
        'user_id',
        'group_id',
        'id'
    );



// Group.php
public function users() 
    return $this->belongsToMany(
        User::class,
        'group_class',
        'group_id',
        'user_id',
        'id'
    );

routes/web.php

Route::get('/test', function () 
    $me = App\User::first();

    $group = App\Group::with('users')->first();

    foreach ($group->users as $user_index => $user) 

        // Show all users (a.k.a members) of this group, except myself
        if ($user->id == $me->id) 
            unset($group->users[$user_index]);
        
    

    return $group;
):

结果:


    "id": 1,
    "name": "ABC Group",
    "users":  // This should be array right?
        "1":  // This should be start with 0
            "id": 2,
            "name": "...",
            "email": "...",
        ,
        "2":  // This should be 1
            "id": 3,
            "name": "...",
            "email": "...",
        
    

我尝试过的:

#1 将values() 放在foreach 循环的末尾,如:

    foreach ($group->users as $user_index => $user) 

         // Show all users (a.k.a members) of this group, except myself
         if ($user->id == $me->id) 
              unset($group->users[$user_index]);
         

         $group->users->values(); // Not working
    

#2 将values() 放在foreach 循环之后,例如:

    Route::get('/test', function () 
         $me = App\User::first();

         $group = App\Group::with('users')->first();

         foreach ($group->users as $user_index => $user) 
              // Show all users (a.k.a members) of this group, except myself
              if ($user->id == $me->id) 
                   unset($group->users[$user_index]);
              
         

         $group->users->values(); // Still not working

         return $group;
    ):

预期结果:


    "id": 1,
    "name": "ABC Group",
    "users": [ // Array
         // index 0
            "id": 2,
            "name": "...",
            "email": "...",
        ,
         // index 1
            "id": 3,
            "name": "...",
            "email": "...",
        
    ]

问:使用unset()后,如何重新索引集合数组?

提前致谢

【问题讨论】:

【参考方案1】:

这里有一些东西要解压,可能会对你有所帮助。

首先,您的查询返回一个 Laravel collection 的用户附加到单个模型 Group。 Laravel 在后台有一点魔力,它也允许使用数组表示法,但可能最容易将其视为出于您的目的而使用的集合。在某些情况下,您可以使用 Laravel 的 toArray() 方法将其转换为数组,例如:

$userArray = $group->users->toArray();

要删除索引,或者在本例中是来自Group 用户的user,请查看forget() 方法,该方法适用于collection 对象。

但是,我认为您可能希望从相反的角度来解决这个问题...在单个查询中提取不需要的索引,而不是事后必须循环遍历集合。像这样的东西可能对你有价值:

$me = App\User::first();

$group = App\Group::with(['users'  => function($query) use($me)
        $query->where('users.id', '!=', $me->id);
    ])->first();

此查询将从集合中删除不需要的用户直接从数据库中删除,无需额外的代码,这正是我认为您所追求的。

HTH。

【讨论】:

以上是关于Laravel:使用 unset() 后无法在急切加载中重新索引集合的数组的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 在急切加载时使用 Eloquent 选择特定列

laravel eloquent - 在嵌套急切加载的关系上不使用

Laravel/Php - 在急切加载关闭中修改集合?

Laravel Eloquent 中的急切加载

使用 laravel 急切加载选择特定列不起作用

Laravel 急切加载与显式连接