【问题标题】:Laravel delete all belongsToMany relations in belongsToMany relationLaravel删除belongsToMany关系中的所有belongsToMany关系
【发布时间】:2018-05-19 11:02:56
【问题描述】:

我有一个 Tournament 模型,其中包含与 Session 模型的 belongsToMany 关系:

class Tournament extends Model{

    public function sessions(){
        return $this->belongsToMany(Session::class, 'tournament_has_sessions');
    }
}

然后我的会话模型包含与 User 模型的 belongsToMany 关系:

class Session extends Model{

    public function users(){
        return $this->belongsToMany(User::class, 'session_has_users');
    }

}

现在,当我删除锦标赛时,我想用它删除 session_has_users 表中的所有会话和所有信息。

我试过了:

$tournament->sessions()->with('users')->delete(); -- < This
$tournament->sessions()->delete();
$tournament->users()->detach();
$tournament->delete();

但它不起作用。 session_has_users 表中的数据持久化

我意识到我可以这样做:

DB::table('session_has_users')->whereIn('session_id', $this->sessions()->pluck('id'))->delete();

但是有没有更有效/更方便(或者如果不是更有效的话,甚至是替代方法)的方式来实现这一点?

【问题讨论】:

    标签: laravel laravel-5 eloquent


    【解决方案1】:

    对外键使用 RDBMS 引用操作

    在数据库模式中,您应该使用ON DELETE CASCADE 操作定义外键。这会在引用的id被删除时自动删除相关记录。

    (有关 Laravel 迁移文件中的示例行,请参阅 dbudimir 的回答)


    使用 Eloquent 分离所有相关模型

    如果你没有使用外键或者你的数据库不支持引用操作,你可以使用这个:

    $tourament->sessions()->sync([]);
    

    sync 方法接受要放置在中间表上的 ID 数组。任何不在给定数组中的 ID 都将从中间表中删除。所以,这个操作完成后,中间表中只会存在给定数组中的ID:

    https://laravel.com/docs/5.5/eloquent-relationships#updating-many-to-many-relationships

    提供一个空数组应该会删除所有的关系。

    【讨论】:

    • 谢谢,我想我会调查一下您所说的ON DELETE CASCADE 参考操作
    【解决方案2】:

    在'tournament_has_sessions'表中你可以像这样设置onDelete('cascade')

    $table->integer('tournament_id')->unsigned()->nullable();
    $table->foreign('tournament_id')->references('id')->on('tournaments')->onDelete('cascade');    
    $table->integer('session_id')->unsigned()->nullable();
    $table->foreign('session_id')->references('id')->on('sessions')->onDelete('cascade');
    

    并且在删除比赛时会自动删除该表中的所有记录

    【讨论】:

    • +1 这是在 Laravel 迁移的表定义中设置 ON DELETE CASCADE 引用操作的方式。如果您当前没有外键但表已经迁移,请忽略整数行。
    【解决方案3】:

    您可以使用以下任何一种:

    $tourament-&gt;sessions()-&gt;detach();

    $tourament-&gt;sessions()-&gt;sync([]);

    或者您可以像上面的答案一样使用 ON DELETE CASCADE 定义外键

    【讨论】:

      猜你喜欢
      • 2015-02-22
      • 1970-01-01
      • 2018-03-08
      • 2021-03-22
      • 2021-10-17
      • 2019-07-08
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      相关资源
      最近更新 更多