【问题标题】: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);
}

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

【问题讨论】:

    标签: php laravel phpmyadmin relationship one-to-many


    【解决方案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 我已经更新了我的答案。希望能回答你的问题。
    猜你喜欢
    • 2014-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-05
    相关资源
    最近更新 更多