从一对多关系中删除记录

Posted

技术标签:

【中文标题】从一对多关系中删除记录【英文标题】:Delete record from one-to-many relationship 【发布时间】:2021-01-01 17:07:35 【问题描述】:

我有 3 张桌子:

用户

id
role
email
typable_id
typable_type

买家

id
name
address
avatar
email
residential_id

住宅

id
name
city 
state

这是我展示这种关系的模型

User.php

public function typable()

  return $this->morphTo();

Buyer.php

public function residential()

  return $this->belongsTo(Residential::class);


public function user()

  return $this->morphMany(User::class, 'typable');

Residential.php

public function buyer()

  return $this->hasMany(Buyer::class);

如果我想删除住宅,则需要删除该住宅的所有买家。与删除买家时也需要删除用户相同。我怎样才能做到这一点?这就是我的住宅控制器内部的销毁功能。

住宅控制器

public function destroy(Request $request) 
    
        $residentials = Residential::find($request->input('id'));
        $residentials->id = $request->input('id');
        $residentials->name = $request->input('name');
        $residentials->delete($residentials);

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

我已尝试将此代码用于删除买家(对于尚未使用的用户)在 destroy() 中,但要删除的买家没有任何更改。 $buyers = Buyer::where('residential_id','=',$request->residential_id)->first();$buyers->delete($buyers);

虽然这是我想删除买家时设法执行的代码,但用户也被删除了。

BuyerController

public function destroy(Request $request)

  $users = User::where('email', '=', $request->email)->first();
  $buyers = Buyer::find($request->input('id'));
  $buyers->id = $request->input('id');
  $buyers->name = $request->input('name');
  $buyers->delete($buyers);
  $users->delete($users);

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

希望有人帮助并教我正确的方法。

【问题讨论】:

【参考方案1】:

方法一

您可以覆盖任何模型的删除功能。

//Residential.php
public function delete()

    $this->buyer->delete(); 
    return parent::delete();


//Buyer.php
public function delete()

    $this->user->delete(); 
    return parent::delete();

现在,当您删除任何住宅记录时,连锁店将首先删除任何相关用户,然后删除买家,最后删除住宅记录。

方法 2

您可以使用each()方法获取所有相关买家,然后获取所有相关用户。

$residentials->buyer
->each(function ($b) 
    $b->user->each(function ($u) 
        $u->delete();
    );
    $b->delete();
);
$residentials->delete();

【讨论】:

我使用第二种方法,它有效!非常感谢!!【参考方案2】:

您可能想注册model events 来处理这个问题:

class Residential extends Model

    // Lets use plural form for a HasMany relationship.
    public function buyers()
    
        return $this->hasMany(Buyer::class);
    

    protected static function booted()
    
        static::deleting(function ($user) 
            // I am using Higher Order Message, check this out: https://laravel.com/docs/8.x/collections#higher-order-messages
            $this->buyers->each->delete();
        );
    



class Buyer extends Model

    // Lets use the plural form for a MorpMany relationship.
    public function users()
    
        return $this->morphMany(User::class, 'typable');
    

    protected static function booted()
    
        static::deleting(function ($user) 
            $this->users->each->delete();
        );
    


你只需要在你的控制器中移除一个对象:

class ResidentialController

    public function destroy(Request $request)
    
        $residential = Residential::findOrFail($request->input('id'));
    
        $residential->delete();

        // The framework is gonna automatically convert this to a JSON object. 
        return $residential;
    


class BuyerController

    public function destroy(Request $request)
    
        $buyer = Buyer::findOrFail($request->input('id'));
    
        $buyer->delete();

        // The framework is gonna automatically convert this to a JSON object. 
        return $buyer;
    

【讨论】:

您可以使用$this->users()->delete() 来简化查询 好点@KennyHorna。这在这种情况下肯定有效。但如果 User 模型包含更多事件,则不会触发这些事件。所以我的代码稍微好一点。 那么不用再在destroy()的住宅控制器中查询了吗? 哦,删除住宅的查询需要在那里,否则我怎么删除它,对吧? @IrdinaZulkeflee 我已经更新了我的答案。希望能回答你的问题。

以上是关于从一对多关系中删除记录的主要内容,如果未能解决你的问题,请参考以下文章

无法删除一对多关系中的记录 laravel eloquent

神奇的记录删除所有孩子的一对多关系

从 2 个表中获取记录数 - 一对多关系

SWIFT - Coredata删除关系记录

NHibernate 不会删除一对多关系中的孤儿

核心数据:删除最后一个具有一对多关系的实体