嵌套的 foreach 循环使用 if 条件创建重复记录 - PHP Laravel 8

Posted

技术标签:

【中文标题】嵌套的 foreach 循环使用 if 条件创建重复记录 - PHP Laravel 8【英文标题】:Nested foreach loop creating duplicate records with if condiotion - PHP Laravel 8 【发布时间】:2022-01-20 23:15:44 【问题描述】:

问题:有模块、用户和 user_modules 表,管理员可以在其中为用户分配多个具有权限的模块。管理员可以更新已分配给该用户的模块权限,未分配的模块应加载到同一张表的刀片视图中。

但问题是数据重复

我正在发布带有图片的代码

管理员控制器:

$modules = Module::all();
$user_modules = User_module::with('module')->where('user_id', $user_id)->get();
return view('admin/seller_assign_modules', compact('user','modules','user_modules'));

seller_assign_modules.blade.php

<table class="table table-striped">
    <thead>
        <tr>
           <th>Modules</th>
           <th>Add</th>
           <th>Edit</th>
           <th>View</th>
           <th>Delete</th>
        </tr>
    </thead>
    <tbody>
                            
     @foreach ($user_modules as $user_mod)
           @foreach ($modules as $mod)
                                
                @if ($mod->id == $user_mod->module_id)
                     <tr>
                           <td scope="row">$user_mod->module->name</td>
                           <td scope="row">$user_mod->add</td>
                           <td scope="row">$user_mod->edit</td>
                           <td scope="row">$user_mod->view</td>
                           <td scope="row">$user_mod->del</td>
                     </tr> 
                @else
                     <tr>
                           <td scope="row">$mod->name</td>
                           <td scope="row"></td>
                           <td scope="row"></td>
                           <td scope="row"></td>
                           <td scope="row"></td>
                     </tr>
                @endif

         @endforeach
     @endforeach

    </tbody>
</table>

模块表:

user_modules 表:

seller_assign_modules.blade.php 的结果

我需要这个:

【问题讨论】:

你不需要循环模块,因为你获取了 user_modules。 @NipunTharuksha,好的,但我也想显示不在 user_modules 表中但在 modules 表中的模块。 模块模型中有用户关系吗? 还没有,还在调试中。你可以建议我。 【参考方案1】:

这里的问题是,Module 有很多User_modules,但你只需要一个。

因此,在这种情况下,一种方法是将user_module 之类的新属性映射到每个Module

管理员控制器

$modules = Module::all();
$userModeules = User_module::where('user_id', $user->id)->get();

$modules = $modules->map(function($module) 
    $module->user_module = $userModules->firstWhere('module_id', $module->id);

    return $module;
);

return view(
    'admin/seller_assign_modules',
    compact('modules')
);

seller_assign_modules.blade.php

<tbody>
  @foreach($mdules as $module)
    <tr>
      <td scope="row"> $module->name </td>
      <td scope="row"> optional($module->user_module)->add </td>
      <td scope="row"> optional($module->user_module)->edit </td>
      <td scope="row"> optional($module->user_module)->view </td>
      <td scope="row"> optional($module->user_module)->del </td>
    </tr>
  @endforeach
</tbody>

【讨论】:

【参考方案2】:

您可以执行以下操作(但这不是一个好方法)

$user_modules = User_module::with('module')->where('user_id', $user_id)->get();
//Get modules where user dont have records
$non_user_modules = Module::whereNotIn('id', (clone $user_modules)->pluck('module_id')->toArray())->get();
        
return view('admin/seller_assign_modules', compact('user','modules','user_modules','non_user_modules'));

然后在刀片中

 @foreach ($user_modules as $user_mod)
     
                 <tr>
                       <td scope="row">$user_mod->module->name</td>
                       <td scope="row">$user_mod->add</td>
                       <td scope="row">$user_mod->edit</td>
                       <td scope="row">$user_mod->view</td>
                       <td scope="row">$user_mod->del</td>
                 </tr> 
          

 @endforeach

 @foreach ($non_user_modules as $non_user_module)
     
                 <tr>
                       <td scope="row">$non_user_module->name</td>
                       <td scope="row"></td>
                       <td scope="row"></td>
                       <td scope="row"></td>
                       <td scope="row"></td>
                 </tr>
          

  @endforeach

你能做的最好的方法

在 Module 模型上建立关系,例如 userModules()

然后得到如下的模块

$modulesWithUser = Module::with(['userModules' => function($userQuery)
            $userQuery->where('user_id',$user_id);
        ])->get();

然后在blade中循环$modulesWithUser并在循环内访问其关系以显示用户权限。

【讨论】:

以上是关于嵌套的 foreach 循环使用 if 条件创建重复记录 - PHP Laravel 8的主要内容,如果未能解决你的问题,请参考以下文章

具有嵌套 forEach 和 for 循环的函数不会返回 false

如何打破嵌套的foreach循环然后转到c#上的父foreach循环

JSTL 中c:forEach 嵌套c:if

Laravel 刀片表创建嵌套的 Foreach 循环

Python基础之if判断,while循环,循环嵌套

结合“if”和“while”,当“if”条件满足时如何跳出所有嵌套循环?