laravel 从与模型相关的多个表中获取数据

evrscar2  于 2022-11-18  发布在  其他
关注(0)|答案(1)|浏览(123)

我有一个comments表,其中包含更多相关表。
comments表格:

id | comment
1  | This is comment 1
2  | This is comment 2

每个评论都可以有一个决定,有或没有服务,有或没有等级。
decisions表格:

id | decision
1  | This is decision 1
2  | This is decision 2

services表格:

id | service
1  | This is service 1
2  | This is service 2

grades表格:

id | grade
1  |   1
2  |   2
3  |   3
4  |   4

然后,为了将这些表组合在一起,我又创建了两个表:comment_decision表格:

id | decision_id | comment_id
1  |      1      |     1
2  |      1      |     2

一条评论只有一个决定。
comment_services表格:

id | service_id | grade_id (nullable) | comment_id
1  |     1      |          null       |      1
2  |     2      |          2          |      1
3  |     2      |          3          |      2

一个注解有多个服务,这些服务可能有也可能没有grade_id
我试图获取每个评论1决定,0或更多的服务或没有等级。
Comment型号:

//To get main comment data + decision
public function decision(){
    return $this->belongsToMany(Decision::class, 'comment_decision', 'comment_id', 'decision_id', 'id');
}

//To get services
public function services(){
    return $this->belongsToMany(Service::class, 'comment_services', 'comment_id', 'service_id', 'id', 'id');
}

这两个函数都按预期工作,并返回所需的数据。但对于成绩,它工作得不好。
Service型号:

public function grade(){
    return $this->hasOneThrough(Grade::class, Service::class, 'service_id', 'id', 'id', 'grade_id');
}

CommentController

public function edit(Request $request, ApplicationComment $comment){
    return view('comments.edit', compact('comment');
}

结果应该是这样的:

array:4 [▼
    "id" => 1
    "comment" => "This is comment 1"
    "decision" => array:1 [▼
        0 => array:4 [▼
            "decision_id" => 9
            "comment_id" => 1
            "pivot" => array:2 [▶]
        ]
    ]
    "services" => array:2 [▼
        0 => array:6 [▼
            "id" => 1
            "service" => "This is service 1"
            "pivot" => array:2 [▶]
            "grades" => null
        ]
        1 => array:6 [▼
            "id" => 2
            "service" => "This is service 1"
            "pivot" => array:2 [▶]
            "grades" => array:3 [▼
                "id" => 1
                "grade" => "1"
                "laravel_through_key" => 2
            ]
        ]
    ]
]

问题是,如果我有多个具有相同service_id的注解,它将返回具有该service_id的第一行。
如果我在comment_services中有以下数据:

id | service_id | grade_id | comment_id
1  |     1      |    null  |     1
2  |     2      |     3    |     1
3  |     3      |    null  |     1
4  |     2      |      2   |     2

在这种情况下,service_id = 2存在两次,第一次是grade_id = 3,第二次是grade_id = 2。对于hasOneThrough,它总是返回第一个:

id | service_id | grade_id | comment_id
2  |     2      |     3    |     1

我尝试了hasManyThrough,但它返回两行:

id | service_id | grade_id | comment_id
2  |     2      |     3    |     1
4  |     2      |     2    |     2
ozxc1zmp

ozxc1zmp1#

从短期来看,我认为你可以这样做:

public function grade(int $comment_id){
    return $this->hasOneThrough(Grade::class, Service::class, 'service_id', 'id', 'id', 'grade_id')->where('comment_id', '=', $this->comment_id);
}

由于此方法返回生成器,因此现在可以通过以下方式获取它:

$comment->service->each(function(Service $service){ echo $service->grade->id });

但是从长远来看,我建议重新组织你收集和存储这些数据的方式。在我看来,这是建立错误的方式。

相关问题