You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Observer的deleted()函数如何使用已删除模型数据?

解决Laravel Observer删除后无法获取模型数据的问题

下面给你几个可行的解决思路:

1. 传递模型必要属性而非整个实例

既然deleted方法触发时模型已从数据库删除,你可以在deleted方法中先提取任务所需的关键数据,将这些数据直接传给任务,而非依赖整个模型对象。

修改Observer的deleted方法:

public function deleted(Company $company)
{
    // 提取外部API需要的标识符
    $customerIdentifier = $company->collection_identifier;
    dispatch(new ExternalAPIDeleteCustomer($customerIdentifier));
}

然后调整ExternalAPIDeleteCustomer任务的逻辑:

class ExternalAPIDeleteCustomer implements ShouldQueue
{
    private $customerIdentifier;

    public function __construct(string $customerIdentifier)
    {
        $this->customerIdentifier = $customerIdentifier;
    }

    public function handle()
    {
        $response = Http::withHeaders([
            'X-Api-Key' => 'API-KEY',
            'X-Api-Secret' => 'API-SECRET'
        ])->delete("https://EXTERNAL.API/v1/customers/{$this->customerIdentifier}");
    }
}

这种方式让任务不再依赖已删除的模型实例,直接使用提前提取的标识符即可完成API调用。

2. 启用软删除(业务场景允许的话)

如果你的业务可以接受软删除(仅标记记录为已删除,而非物理删除),可以给Company模型启用软删除特性:

首先在模型中引入软删除Trait:

use Illuminate\Database\Eloquent\SoftDeletes;

class Company extends Model
{
    use SoftDeletes;
}

然后生成并执行软删除迁移:

php artisan make:migration add_deleted_at_to_companies_table --table=companies

迁移文件内容:

public function up()
{
    Schema::table('companies', function (Blueprint $table) {
        $table->softDeletes();
    });
}

public function down()
{
    Schema::table('companies', function (Blueprint $table) {
        $table->dropSoftDeletes();
    });
}

启用软删除后,执行删除操作时模型不会被物理删除,deleted方法触发时你仍能正常访问模型的所有属性,原任务代码无需修改即可正常运行。后续若需要清理软删除记录,可通过定时任务执行Company::onlyTrashed()->forceDelete()。

3. 自定义Nova的删除动作

既然Laravel Nova不支持触发deleting观察者方法,你可以直接在Nova的Company资源中自定义删除逻辑,先分发任务再执行删除:

修改Nova的Company资源文件:

use Laravel\Nova\Actions\Action;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Http\Requests\NovaRequest;

class Company extends Resource
{
    // ... 其他资源配置代码

    public function actions(NovaRequest $request)
    {
        return [
            Action::make('删除客户')
                ->confirmText('确定要删除这个客户吗?')
                ->confirmButtonText('删除')
                ->cancelButtonText('取消')
                ->handle(function (ActionFields $fields, $models) {
                    foreach ($models as $model) {
                        // 先分发删除任务(此时模型未删除,可正常获取属性)
                        dispatch(new ExternalAPIDeleteCustomer($model));
                        // 再执行模型删除
                        $model->delete();
                    }

                    return Action::message('客户已删除并同步到外部API');
                })
                ->destructive(),
        ];
    }

    // 隐藏Nova默认的删除按钮,强制使用自定义动作
    public function authorizedToDelete(Request $request)
    {
        return false;
    }
}

这样用户在Nova后台删除记录时,会先触发API同步任务,再执行模型删除,完美避开deleted方法无法获取模型数据的问题。


内容的提问来源于stack exchange,提问作者Louis Sallée-Delille

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 12:35:14