简介
我们在删除一条数据时,需要删除其关联数据,如删除用户后连带删除其创建的文章和图片。
从实现机制有两种类型
代码监听器
利用 Eloquent 监控器 的 deleted 事件连带删除,好处是灵活、扩展性强,不受底层数据库约束,坏处当删除时不添加监听器,就会出现漏删
外键约束
利用 MySQL 自带的外键约束功能,好处是数据一致性强,基本上不会出现漏删,坏处是有些数据库不支持,如 SQLite
代码监听器
利用 Eloquent 监控器实现删除,也有两种方式,
第一种可以直接在模型类中实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21class User extends Eloquent
{
public function photos()
{
return $this->hasMany('Photo');
}
public function posts()
{
return $this->hasMany('Post');
}
protected static function boot()
{
parent::boot();
static::deleting(function($user) {
$user->photos()->delete();
$user->posts()->delete();
});
}
}第二种方式是先创建UserObserver (观察者),
1
2
3
4
5
6
7class UserObserver
{
public function deleting(User $user)
{
//
}
}
然后在AppServiceProvider中的boot中设置监听事件1
2
3
4
5
6
7class AppServiceProvider extends ServiceProvider
{
public function boot()
{
\App\Models\User::observe(\App\Observers\UserObserver::class);
}
}
外键约束
如新建数据库迁移类1
php artisan make:migration add_references
然后在add_references中添加1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32class AddReferences extends Migration
{
public function up()
{
Schema::table('topics' , function(Blueprint $table){
// 当 user_id 对应的 users 表数据被删除时,删除词条
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade') ;
});
Schema::table('replies', function (Blueprint $table) {
// 当 user_id 对应的 users 表数据被删除时,删除此条数据
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
// 当 topic_id 对应的 topics 表数据被删除时,删除此条数据
$table->foreign('topic_id')->references('id')->on('topics')->onDelete('cascade');
});
}
public function down()
{
Schema::table('topics' , function(Blueprint $table){
// 移除外键约束
$table->dropForeign(['user_id']);
});
Schema::table('replies', function (Blueprint $table) {
$table->dropForeign(['user_id']);
$table->dropForeign(['topic_id']);
});
}
}
运行迁移1
php artisan migrate