我有两台User型和Modules型的 Modules具有具有许多子代的递归父母/子代关系(SubModules).

另一方面,用户可以具有许多模块和许多子模块(访问它们的权限),因此它们在N到N表users_modules

所以我想提取用户的所有模块,但这些模块只需要包括与用户相关的子模块.

现在,我的控制器中有类似这样的东西:

auth()->user()->modules->toArray();

但我不知道如何过滤那些子模块.

以下是我的模型(没有任何更改,因为我try 的所有模型都不起作用):

User

class User extends Authenticatable
{
   ...
    public function modules()
    {
        return $this->belongsToMany(Module::class, 'modules_users')->where('group', null)->with('subModules');
    }

Module

class Module extends Model
{
   ...

    public function users()
    {
        return $this->belongsToMany(User::class, 'modules_users');
    }

    public function subModules()
    {
        return $this->hasMany(Module::class, 'group');
    }

    public function parent(): BelongsTo
    {
        return $this->belongsTo(Module::class, 'group');
    }
}

有人能帮帮我吗?

推荐答案

Edit

根据我们反复得到的意见,我认为你所遇到的问题是我所理解的.您需要访问其中subModules属于用户的user.modules.subModules,并维护您的模块对象的相关树.

好消息是Laravel允许在这with()个调用中注入查询逻辑.你可以这样做:

$userId = 5; // auth()->id();
$user = User::query()->where('id', $userId)
    ->with('modules.subModules', function ($query) {
        $query->whereHas('users', fn ($subQuery) => $subQuery->where('id', $userId));
    })
    ->first();

dd($user->toArray());

这将在本地为我输出以下对象:

enter image description here

现在,作为概念验证,如果我在parent_id设置为1的情况下再附加subModule,我应该在sub_modules对象中看到这一点

enter image description here

我的建议是考虑我在原始答案中推荐的库,但上面的查询相当简单,它获取数据和创建对象的方式存在限制,但这完全取决于您需要获得的复杂程度.


Original Answer

这里有几种解决方案,我认为最好的方法在一定程度上取决于您的数据 struct .

try 访问数据的最简单也可能是最好的方法是在with()调用的第一个参数中使用Laravel的.语法.

$user = User::inRandomOrder()->with('modules.subModules')->first()

enter image description here

这种方法的主要缺点是subModules()分的深度.这将限于用户可能所属的任何模块的直接子模块.

如果我将查询更新为另一个级别subModules,您可以看到我的模块6有自己的子模块.

$user::query()->where('id', 5)->with('modules.subModules.subModules')->first();

enter image description here

另一种可能的解决方案是访问第三方图书馆,以帮助您更轻松地访问嵌套关系.

看一下kalnov/nestedset,其中有很多,但它将向您的模型添加以下方法:

$result = Category::whereDescendantOf($node)->get();
$result = Category::whereNotDescendantOf($node)->get();
$result = Category::orWhereDescendantOf($node)->get();
$result = Category::orWhereNotDescendantOf($node)->get();
$result = Category::whereDescendantAndSelf($id)->get();

// Include target node into result set
$result = Category::whereDescendantOrSelf($node)->get();

我猜这可能就是您在应用程序上下文中寻找的内容,其中用户试图访问的内容已以某种方式追溯到用户.如果用户也可以属于不同级别的模块,这很容易令人毛骨悚然.

Php相关问答推荐

PHP,ZipArchive删除一个空文件?

MariaDB 11.3.2+PHP:服务器向客户端发送未知的字符集(0).请向开发人员报告

PHP中的圆生成器在国际日期变更线上失败

PHP原始数据读取引发max_input_vars错误

在PHP中读取JSON

PHP Laravel Web应用启动时间&>15秒

当配置的URL为空时禁用Laravel Slack日志(log)记录

如果为布尔值,则 for each 循环重新启动

CKEDITOR-如何在PHP中判断提交后的空数据

拉威尔10有许多通过获取所有祖父母数据的子元素S图像

WooCommerce在收据页面获取产品下载URL

在WooCommerce管理中为订单项目添加自定义字段价格值

将数据推入所有子数组条目

Wordpress,配置一周第一天选项

Google Drive API:为什么使用服务帐户在下载文件时会将我带到 Google Drive 登录窗口?

如何将文件上传添加到 WooCommerce 结帐?

如何使用不同的方法编写嵌套连接查询并将两列连接成一列在 laravel 查询生成器中

Shopware 6 AuthControllerDecorator已弃用

在 Botiga 主题模板中添加复选框到政策行.Woocommerce

按数字然后按字符串对关联 PHP 数组进行排序