Laravel-Backpack:结合 hasMany 和 hasManyThrough 在列表中添加子句
Posted
技术标签:
【中文标题】Laravel-Backpack:结合 hasMany 和 hasManyThrough 在列表中添加子句【英文标题】:Laravel-Backpack: combine hasMany and hasManyThrough to add clauses in list 【发布时间】:2021-10-23 04:36:36 【问题描述】:这是我所拥有的:
用户表
以“project_id”作为列之一的实例表
项目表
带有“user_id”和“instance_id”的instance_user表
带有“user_id”和“project_id”的project_user表
当我创建用户时,我希望能够通过 select2_multiple 将项目和/或实例与用户相关联,将条目添加到数据透视表中。到这里为止,一切正常。
然后,当用户登录时,在实例列表中,我希望他们只看到他们在“instance_user”表中关联的实例以及属于他们在“project_user”中关联的项目的实例桌子。所以,例如:
用户:
id | name |
---|---|
1 | Example1 |
2 | Example2 |
实例:
id | name | project_id |
---|---|---|
1 | Instance1 | 1 |
2 | Instance2 | 1 |
3 | Instance3 | 2 |
4 | Instance4 | 2 |
5 | Instance5 | 2 |
instance_user:
instance_id | user_id |
---|---|
4 | 1 |
project_user:
project_id | user_id |
---|---|
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。
有没有办法做到这一点,一个函数可以返回具有给定限制的组合结果?或有关如何解决此问题的任何提示。
非常感谢。
【问题讨论】:
【参考方案1】:即使我的回答得到了预期的结果,当有数百万条记录时,这也不是获取实例的好方法。所以你最好找一个 不同的方式来实现这一点。最有可能尝试拥有 db 表 修改,您可以在其中获取某个用户的所有实例。
这是您可以根据您的表结构使用的方法。
-
通过
instance_user
获取实例ID
通过project_user
获取实例ID
合并 ID
通过合并的 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"
]
性能
【讨论】:
如果我的回答回答了您的问题,希望您可以将其标记为答案。谢谢 谢谢!你的代码给了我一个关于如何解决这个问题的想法并且它有效。我确信有很多更好、更优雅的解决方案,但由于是一个非常小的项目(最多 200 个实例和 20-30 个项目),我会选择它。【参考方案2】:这就是我最终要做的。很高兴看到不同的方法。
//InstanceCrudController
public function get_instance_ids($user_id)
$user = User::find($user_id);
$instance_ids_via_instance_user = $user->instances->pluck('id')->toArray();
$instance_ids_via_project_user = Instance::whereIn('project_id', $user->projects->pluck('id')->toArray())->pluck('id')->toArray();
$instance_ids = array_merge($instance_ids_via_instance_user,$instance_ids_via_project_user);
return $instance_ids;
CRUD::addClause('whereIn', 'id', $this->get_instance_ids(backpack_user()->id));
【讨论】:
以上是关于Laravel-Backpack:结合 hasMany 和 hasManyThrough 在列表中添加子句的主要内容,如果未能解决你的问题,请参考以下文章
laravel Eloquent 查询 WhereHas 结果错误