Laravel 5:如何更新与多对多相关的项目(删除+添加)

Posted

技术标签:

【中文标题】Laravel 5:如何更新与多对多相关的项目(删除+添加)【英文标题】:Laravel 5: how to update items (remove+add) in relation many to many 【发布时间】:2021-08-24 17:26:55 【问题描述】:

我使用的是 Laravel 5。有一个多对多的关系

class Visit extends Model 

    public function visitors(): HasMany
    
        return $this->hasMany(Visitor::class);
    

从请求中,我得到所有访问者的 json 格式数据,属于访问

[
    
        "visitor_id": 111,
        "type": "owner"
    ,
    
        "visitor_id": 222,
        "type": "seller"
    ,
    
        "visitor_id": 444,
        "type": "buyer"
    ,
]

访问最初可以有访问者

[
    
        "visitor_id": 111,
        "type": "owner"
    ,
    
        "visitor_id": 222,
        "type": "seller"
    ,
    
        "visitor_id": 333,
        "type": "buyer"
    ,
]

我需要更新访问者:删除已消失的访问者,添加新访问者并忽略现有访问者。请注意,该访问者还有其他标志 - “类型”,我应该考虑到这一点。 所以结果应该和第一个例子一样

【问题讨论】:

规则不明确,需要多解释。但也许你想使用sync 【参考方案1】:

我没有找到任何其他解决方案,然后进行了 2 个操作:一个用于删除,另一个用于插入。

class VisitController

    private function updateVisitors(Visit $visit, Collection $newVisitors): void
    
        $newVisitorsPluck = [];
        foreach ($newVisitors as $visitor) 
            $newVisitorsPluck[$visitor->getId()] = $visitor->getType();
        

        $existingVisitors = $visit->Visitors()->pluck('visitor_type', 'visitor_id')->toArray();

        $this->deleteRemovedVisitors($visit, $newVisitorsPluck, $existingVisitors);

        $this->addNewVisitors($visit, $newVisitorsPluck, $existingVisitors);
    

    private function deleteRemovedVisitors(Visit $visit, array $newVisitors, array $existingVisitors): void
    
        $deleteItems = array_diff_assoc($existingVisitors, $newAVisitors);

        foreach ($deleteItems as $visitorId => $visitorType) 
            DB::table('visitors_table')
                ->where('visit_id', '=', $visit->getKey())
                ->where('visitor_id', '=', $visitorId)
                ->where('visitor_type', '=', $visitorType)
                ->delete();
        
    

    private function addNewVisitors(Visit $visit, array $newVisitors, array $existingVisitors): void
    
        $addItems = array_diff_assoc($newVisitors, $existingVisitors);

        foreach ($addItems as $visitorId => $visitorType) 
            $visit->Visitors()->save(
                new Visitvisitor([
                ...
                ])
            );
        
    

【讨论】:

以上是关于Laravel 5:如何更新与多对多相关的项目(删除+添加)的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Laravel 5.5 中实现多个多对多关系?

如何更新值多对多 Laravel

如何在多对多关系 Laravel 中检索所有相关模型?

我需要向我的数据库询问从另一个应用程序收到的单词,我的表与多对多关系相关

Laravel 关系多对多按外键计数相关数据

如何在 prisma 中使用 connectOrCreate 与多对多