当我使用以下语法删除行时:
$user->delete();
Run Code Online (Sandbox Code Playgroud)
有没有办法附加各种回调,所以它会自动执行此操作:
$this->photo()->delete();
Run Code Online (Sandbox Code Playgroud)
最好在模型类内.
Chr*_*itz 180
您实际上可以在迁移中进行设置:
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
资料来源:http://laravel.com/docs/5.1/migrations#foreign-key-constraints
您还可以为约束的"on delete"和"on update"属性指定所需的操作:
Run Code Online (Sandbox Code Playgroud)$table->foreign('user_id') ->references('id')->on('users') ->onDelete('cascade');
iva*_*hoe 178
我相信这是Eloquent事件的完美用例(http://laravel.com/docs/eloquent#model-events).您可以使用"删除"事件进行清理:
class User extends Eloquent
{
public function photos()
{
return $this->has_many('Photo');
}
// this is a recommended way to declare event handlers
public static function boot() {
parent::boot();
static::deleting(function($user) { // before delete() method call this
$user->photos()->delete();
// do the rest of the cleanup...
});
}
}
Run Code Online (Sandbox Code Playgroud)
您可能还应该将整个事情放在事务中,以确保参照完整性.
akh*_*khy 48
注意:这个答案是为Laravel 3编写的.因此,在更新版本的Laravel中可能会或可能不会很好.
您可以在实际删除用户之前删除所有相关照片.
<?php
class User extends Eloquent
{
public function photos()
{
return $this->has_many('Photo');
}
public function delete()
{
// delete all related photos
$this->photos()->delete();
// as suggested by Dirk in comment,
// it's an uglier alternative, but faster
// Photo::where("user_id", $this->id)->delete()
// delete the user
return parent::delete();
}
}
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你.
Cal*_*aga 25
用户模型中的关系:
public function photos()
{
return $this->hasMany('Photo');
}
Run Code Online (Sandbox Code Playgroud)
删除记录和相关:
$user = User::find($id);
// delete related
$user->photos()->delete();
$user->delete();
Run Code Online (Sandbox Code Playgroud)
Att*_*lop 14
从Laravel 5.2开始,文档指出应该在AppServiceProvider中注册这些类型的事件处理程序:
<?php
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
User::deleting(function ($user) {
$user->photos()->delete();
});
}
Run Code Online (Sandbox Code Playgroud)
我甚至假设将它们移到单独的类而不是闭包中以获得更好的应用程序结构.
Par*_*ras 14
解决这个问题有3种方法:
1.在模型启动时使用Eloquent事件(参考:https://laravel.com/docs/5.7/eloquent#events)
class User extends Eloquent
{
public static function boot() {
parent::boot();
static::deleting(function($user) {
$user->photos()->delete();
});
}
}
Run Code Online (Sandbox Code Playgroud)
2.使用Eloquent事件观察员(参考:https://laravel.com/docs/5.7/eloquent#observers)
在AppServiceProvider中,像这样注册观察者:
public function boot()
{
User::observe(UserObserver::class);
}
Run Code Online (Sandbox Code Playgroud)
接下来,添加一个Observer类,如下所示:
class UserObserver
{
public function deleting(User $user)
{
$user->photos()->delete();
}
}
Run Code Online (Sandbox Code Playgroud)
3.使用外键约束(参考:https://laravel.com/docs/5.7/migrations#foreign-key-constraints)
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
Run Code Online (Sandbox Code Playgroud)
Constrained()Laravel 7之后,新的foreignId()和constrained()方法可用于定义数据库中的关系约束。OnDelete()可以在这些方法上使用方法来自动删除相关记录。
$table->unsignedBigInterer('user_id');
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
Run Code Online (Sandbox Code Playgroud)
$table->foreignId('user_id')
->constrained()
->onDelete('cascade');
Run Code Online (Sandbox Code Playgroud)
为了详细说明所选答案,如果您的关系还具有必须删除的子关系,则必须首先检索所有子关系记录,然后调用该方法,delete()以便也正确触发它们的删除事件。
您可以使用更高阶的消息轻松地做到这一点。
class User extends Eloquent
{
/**
* The "booting" method of the model.
*
* @return void
*/
public static function boot() {
parent::boot();
static::deleting(function($user) {
$user->photos()->get()->each->delete();
});
}
}
Run Code Online (Sandbox Code Playgroud)
您还可以通过仅查询关系 ID 列来提高性能:
class User extends Eloquent
{
/**
* The "booting" method of the model.
*
* @return void
*/
public static function boot() {
parent::boot();
static::deleting(function($user) {
$user->photos()->get(['id'])->each->delete();
});
}
}
Run Code Online (Sandbox Code Playgroud)
小智 6
最好delete为此重写该方法。这样,您就可以将 DB 事务合并到delete方法本身中。如果您使用事件方式,则delete每次调用它时都必须用数据库事务覆盖您的方法调用。
在你的User模型中。
public function delete()
{
\DB::beginTransaction();
$this
->photo()
->delete()
;
$result = parent::delete();
\DB::commit();
return $result;
}
Run Code Online (Sandbox Code Playgroud)