[英]Laravel-Backpack: combine hasMany and hasManyThrough to add clauses in list
這是我所擁有的:
用戶表
以“project_id”作為列之一的實例表
項目表
具有“user_id”和“instance_id”的 instance_user 表
包含“user_id”和“project_id”的 project_user 表
當我創建用戶時,我希望能夠通過 select2_multiple 將項目和/或實例關聯到用戶,將條目添加到 pivot 表。 到這里為止,一切正常。
然后,當用戶登錄時,在實例列表中,我希望他們只看到他們在“instance_user”表中關聯的實例以及屬於他們在“project_user”表中關聯的項目的實例。 所以,例如:
用戶:
ID | 姓名 |
---|---|
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。
有沒有辦法做到這一點,一個 function 可以返回具有給定限制的組合結果? 或者有關如何處理此問題的任何提示。
非常感謝。
即使我的回答得到了預期的結果,當有數百萬條記錄時,這也不是獲取實例的好方法。 所以你最好找到一種不同的方法來實現這一點。 最有可能嘗試修改數據庫表,您可以在其中獲取特定用戶的所有實例。
這是您可以根據表結構使用的方法。
instance_user
獲取實例 IDproject_user
獲取實例 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"
}
]
表現
這就是我最終要做的。 很高興看到不同的方法。
//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));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.