首页 > 解决方案 > Laravel-Backpack:结合 hasMany 和 hasManyThrough 在列表中添加子句

问题描述

这是我所拥有的:

用户表

以“project_id”作为列之一的实例表

项目表

带有“user_id”和“instance_id”的 instance_user 表

带有“user_id”和“project_id”的 project_user 表

当我创建用户时,我希望能够通过 select2_multiple 将项目和/或实例与用户相关联,将条目添加到数据透视表中。直到这里,一切正常。

然后,当用户登录时,在实例列表中,我希望他们只看到他们在“instance_user”表中关联的实例,以及属于他们在“project_user”表中关联的项目的实例。因此,例如:

用户:

ID 姓名
1 示例 1
2 示例 2

实例:

ID 姓名 项目编号
1 实例1 1
2 实例2 1
3 实例3 2
4 实例4 2
5 实例5 2

实例用户:

instance_id 用户身份
4 1

项目用户:

项目编号 用户身份
1 1

在这里,id=1 的用户会在实例列表中看到 = Instance1, Instance2, Instance4

我尝试在 InstanceCrudController 中添加这个:

CRUD::addClause('has', 'users');
CRUD::addClause('has', 'instances_through');

这些是我的用户和实例模型:

//USER MODEL
    public function instances()
    {
        return $this->belongsToMany(Instance::class);
    }

    public function projects()
    {
        return $this->belongsToMany(Project::class);
    }

//INSTANCE MODEL
    public function users()
    {
        return $this->belongsToMany(User::class);
    }

    public function instances_through()
    {
        return $this->hasManyThrough(
            User::class,
            ProjectUser::class,
            'project_id',
            'id',
            'id', 
            'user_id' 
        );        
    }

但这显然是不正确的,因为它没有显示预期的结果,而且我认为我不太了解在这种情况下如何使用 hasManyThrough 。

有没有办法做到这一点,一个函数可以返回具有给定限制的组合结果?或有关如何解决此问题的任何提示。

非常感谢。

标签: phplaraveleloquentrelationshiplaravel-backpack

解决方案


即使我的回答得到了预期的结果,这也不是在有数百万条记录时获取实例的好方法。所以你最好找到一种不同的方法来实现这一点。很可能尝试修改数据库表,您可以在其中获取某个用户的所有实例。

这是您可以根据表结构使用的方法。

  1. 通过获取实例 IDinstance_user
  2. 通过获取实例 IDproject_user
  3. 合并 ID
  4. 通过合并的 id 查找实例

示例代码。我已经在github/nipunTharuksha/Laravel-Backpack-answer测试了这个和演示项目,我还定义了其他关系。

class InstanceCrudController extends Controller
{
    public function userInstances()
    {
        $user = User::find(1);

        $instance_ids_via_instance_user = (clone $user)->instances()->pluck('instance_id')->toArray(); //Instance id 4
        $instance_ids_via_project_user = Instance::whereIn('project_id', (clone $user)->projects()->pluck('project_id')->toArray())->get()->pluck('id')->toArray(); // Instance is 1,2

        $instance_ids = array_merge($instance_ids_via_instance_user,$instance_ids_via_project_user);

        $instances = Instance::find($instance_ids);

        return response()->json($instances);

    }
}

结果

[
  {
    "id": 1,
    "name": "Prof. Raphaelle Robel DVM",
    "project_id": 1,
    "created_at": "2021-08-22T17:26:54.000000Z",
    "updated_at": "2021-08-22T17:26:54.000000Z"
  },
  {
    "id": 2,
    "name": "Tianna Glover",
    "project_id": 1,
    "created_at": "2021-08-22T17:26:54.000000Z",
    "updated_at": "2021-08-22T17:26:54.000000Z"
  },
  {
    "id": 4,
    "name": "Abigale Cummings",
    "project_id": 2,
    "created_at": "2021-08-22T17:26:54.000000Z",
    "updated_at": "2021-08-22T17:26:54.000000Z"
  }
]

表现

在此处输入图像描述


推荐阅读