news 2026/9/10 9:15:44

Filament 资源记录删除与软删除完整指南:DeleteAction、TrashedFilter 与授权控制

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Filament 资源记录删除与软删除完整指南:DeleteAction、TrashedFilter 与授权控制

Filament 资源记录删除与软删除完整指南:DeleteAction、TrashedFilter 与授权控制

【免费下载链接】filamentA powerful open-source UI framework for Laravel • Build and ship apps & admin panels fast with Livewire项目地址: https://gitcode.com/GitHub_Trending/fi/filament

本文围绕 Filament(基于 Laravel + Livewire 的开源 UI 框架)资源系统中"删除记录"这一核心操作展开,系统讲解在 列表页删除记录、为资源启用软删除(soft-deletes)、恢复(Restore)与强制删除(Force Delete)的完整配置方式,并结合本仓库 packages/actions 与 packages/tables 源码,深入剖析各 Action 的默认行为、TrashedFilter 的查询逻辑以及基于模型 Policy 的授权机制。读完本文,你将能够独立为自己的 Filament 资源接入"删除 → 回收站筛选 → 恢复/强制删除"的完整生命周期,并精确控制单条删除与批量删除的权限边界。

概述:Filament 中的删除操作体系

在 Filament 中,"删除记录"不是一个单一功能,而是一组由 packages/actions 提供的 Action 类组成的完整体系,包括:

Action 类默认名称典型用途底层调用
DeleteActiondelete删除单条记录(软删除模型则软删除)$record->delete()
DeleteBulkActiondelete(批量场景)表格中批量删除多条记录批量查询->delete()或逐条删除
ForceDeleteActionforceDelete强制物理删除软删除记录$record->forceDelete()
RestoreActionrestore恢复已软删除的记录$record->restore()
TrashedFiltertrashed表格筛选:含回收站 / 仅回收站withTrashed()/onlyTrashed()

默认情况下,应用不会展示已删除记录的交互入口;只有当模型使用 Laravel 的SoftDeletestrait 且资源显式接入软删除相关组件后,恢复、强制删除与回收站筛选才会生效。

处理软删除(Soft-deletes)

创建带软删除能力的资源

如果希望资源具备"恢复、强制删除、筛选回收站记录"的能力,最简单的方式是在生成资源时使用--soft-deletes标志:

php artisan make:filament-resource Customer --soft-deletes

该标志由 MakeResourceCommand 定义(InputOptionVALUE_NONE类型),其描述为 "Indicate if the model uses soft-deletes"。命令执行时会自动检测模型是否使用SoftDeletes,并把删除/恢复/强制删除相关的表格动作、筛选器与编辑页头部动作一并生成到资源中。

为已有资源添加软删除功能

对于已经存在的资源,可以按下面步骤手动接入软删除能力。

首先更新资源的table()方法。需要引入相关 Action 与筛选器类,注册TrashedFilter、单条记录动作与批量动作:

use Filament\Actions\BulkActionGroup; use Filament\Actions\DeleteAction; use Filament\Actions\DeleteBulkAction; use Filament\Actions\ForceDeleteAction; use Filament\Actions\ForceDeleteBulkAction; use Filament\Actions\RestoreAction; use Filament\Actions\RestoreBulkAction; use Filament\Tables\Filters\TrashedFilter; use Filament\Tables\Table; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\SoftDeletingScope; public static function table(Table $table): Table { return $table ->columns([ // ... ]) ->filters([ TrashedFilter::make(), // ... ]) ->recordActions([ // 使用 simple resource(单页资源)或希望不离开表格直接删除记录时, // 可以把这些动作挂在表格行上。 DeleteAction::make(), ForceDeleteAction::make(), RestoreAction::make(), // ... ]) ->toolbarActions([ BulkActionGroup::make([ DeleteBulkAction::make(), ForceDeleteBulkAction::make(), RestoreBulkAction::make(), // ... ]), ]); }

接着,覆盖资源的路由绑定查询,移除SoftDeletingScope全局作用域,否则已删除的记录将无法通过路由绑定被解析:

public static function getRecordRouteBindingEloquentQuery(): Builder { return parent::getRecordRouteBindingEloquentQuery() ->withoutGlobalScopes([ SoftDeletingScope::class, ]); }

最后,如果存在编辑页(Edit page),在其getHeaderActions()中加入对应动作:

use Filament\Actions; protected function getHeaderActions(): array { return [ Actions\DeleteAction::make(), Actions\ForceDeleteAction::make(), Actions\RestoreAction::make(), // ... ]; }
动作的可见性逻辑(源码剖析)

从源码看,Filament 会根据记录的软删除状态自动控制上述动作的显隐,无需手工visible()

  • DeleteAction 通过hidden()判断:若模型存在trashed()方法且记录处于已删除状态,则隐藏删除按钮——即"已删除的记录不能再普通删除"。
  • ForceDeleteAction 与 RestoreAction 通过visible()判断:仅当记录存在trashed()方法且确实处于已删除状态时才显示。这保证了"强制删除/恢复"按钮只出现在回收站记录上。
  • DeleteBulkAction 则根据TrashedFilter的当前状态隐藏自身:当回收站筛选被激活且选择的是"仅回收站"时,批量删除按钮被隐藏(此时应改用批量强制删除)。

三个 Action 均默认使用danger色(Restore 为gray)、要求二次确认弹窗(requiresConfirmation()),并提供成功/失败通知。另外 DeleteAction 还注册了mod+d键盘快捷键,方便桌面端快速操作。

TrashedFilter 的查询行为(源码剖析)

TrashedFilter 继承自TernaryFilter(三态筛选器),提供了三个选项:

  • 包含已删除记录(with trashed)$query->withTrashed()
  • 仅已删除记录(only trashed)$query->onlyTrashed()
  • 默认(不含已删除)$query->withoutTrashed()

baseQuery()会调用$query->withoutGlobalScopes([SoftDeletingScope::class]),确保筛选器本身能读取到回收站数据。同时它实现了indicateUsing(),当筛选生效时会在表格上方生成对应的状态指示器,帮助用户明确当前视图是"含回收站"还是"仅回收站"。

在列表页删除记录

表格默认支持批量删除(toolbarActions中的DeleteBulkAction)。如果还需要在表格行上直接删除单条记录,可以在recordActions中加入DeleteAction

use Filament\Actions\DeleteAction; use Filament\Tables\Table; public static function table(Table $table): Table { return $table ->columns([ // ... ]) ->recordActions([ // ... DeleteAction::make(), ]); }

点击行上的删除按钮后,Filament 会弹出确认模态框(modal),确认后执行$record->delete()。若模型启用了软删除,delete()实际执行的是软删除;若未启用,则是物理删除。删除成功后显示成功通知,失败则显示失败通知。

对于批量删除,DeleteBulkAction 的底层实现有两种路径:当不需要逐条授权(默认)时,直接对选中记录的查询执行->delete()(一条 SQL 完成,性能最优);当启用逐条授权时,则遍历每条记录调用$record->delete(),并对失败计数,最终通过通知区分"全部成功 / 部分成功 / 全部失败"三种结果(对应语言包中的deleteddeleted_partialdeleted_none文案)。批量删除完成后会自动取消已选记录(deselectRecordsAfterCompletion())。

授权(Authorization)

Filament 的删除操作会遵循应用中注册的 Laravel 模型策略(Model Policies),无需额外配置。

单条删除与批量删除

  • 当策略的delete()方法返回true时,用户允许删除单条记录。
  • 批量删除(bulk delete)则检查策略的deleteAny()方法。Filament 之所以使用deleteAny()而非逐条检查delete(),是因为对多条记录逐一调用策略方法性能开销过大。

如果业务上确实需要"批量删除时逐条校验delete()",可以在DeleteBulkAction上调用authorizeIndividualRecords()

DeleteBulkAction::make()->authorizeIndividualRecords()

该方法定义在 CanBeAuthorized trait 中,支持布尔值、字符串能力名(Gate::inspect)或闭包三种形式;启用后批量删除将进入逐条授权与逐条处理模式,未通过授权的记录会被跳过并计入失败通知。需要说明的是,逐条授权会牺牲批量删除的部分性能,仅在严格权限场景下推荐使用。

软删除的授权

针对软删除的三个阶段,Filament 使用了独立的策略方法:

操作单条记录策略方法批量操作策略方法
强制删除forceDelete()forceDeleteAny()
恢复restore()restoreAny()
  • forceDelete()用于阻止单条已软删除记录被强制物理删除;forceDeleteAny()用于阻止批量强制删除。
  • restore()用于阻止单条已软删除记录被恢复;restoreAny()用于阻止批量恢复。
  • deleteAny()同理,批量场景使用forceDeleteAny()restoreAny()也是出于性能考虑,避免逐条迭代检查。

因此,只要在对应模型的 Policy 中定义好这六个方法(或其中需要约束的部分),Filament 的删除、强制删除、恢复及对应的批量操作就会自动遵循授权结果,未授权时按钮会被隐藏或操作被拦截。

实战建议与常见陷阱

  1. 路由绑定必须移除全局作用域:为已有资源添加软删除时,务必覆盖getRecordRouteBindingEloquentQuery()withoutGlobalScopes([SoftDeletingScope::class]),否则访问已删除记录的编辑页会直接 404。
  2. 动作显隐是自动的DeleteAction在记录已删除时自动隐藏,ForceDeleteAction/RestoreAction仅在已删除记录上显示,不要手动设置互相冲突的visible()/hidden()
  3. 批量删除性能取舍:默认deleteAny()授权 + 查询级删除是最快路径;authorizeIndividualRecords()会逐条授权与逐条删除,仅在需要严格行级权限时启用。
  4. 配合回收站筛选使用TrashedFilter的三态设计(含回收站 / 仅回收站 / 默认)与批量动作的显隐联动,是构建完整"回收站"体验的关键,详见 tables 包文档 与 表格动作文档。
  5. 测试验证:本仓库在 tests/src/Actions 目录下提供了DeleteActionTest.phpDeleteBulkActionTest.phpForceDeleteActionTest.phpRestoreActionTest.php等测试用例,可作为理解各 Action 行为边界与编写自身测试的参考。

通过本文的配置与源码分析,你可以为任何 Filament 资源快速落地完整的删除生命周期,并确保权限模型与 UI 行为严格一致。

【免费下载链接】filamentA powerful open-source UI framework for Laravel • Build and ship apps & admin panels fast with Livewire项目地址: https://gitcode.com/GitHub_Trending/fi/filament

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 9:07:02

STM32循迹避障小车设计与实现:状态机、PID调参与传感器融合

简介:这是一套基于STM32芯片的循迹避障小车完整资料源码,主要面向正在准备毕业设计、课程设计或期末大作业的计算机、电子类专业学生,也适合希望动手实践嵌入式开发的学习者。资源以高分毕业设计为背景,评审达到99分,代…

作者头像 李华
网站建设 2026/9/10 9:06:56

AI驱动抗衰老药物临床验证:Rentosertib与衰老时钟数据解读

这条消息在药物研发圈里刷屏的时候,我的第一反应不是转群,而是去找原始项目资料。英矽智能的 Rentosertib 进入人体临床试验,同时研究团队公布了用 6 种衰老时钟评估受试者预测年龄的结果——用药后预测年龄出现下降。对不关注这个领域的人来…

作者头像 李华
网站建设 2026/9/10 9:06:34

降AI率工具横评:十款主流AI改写工具实测对比

只要和AI写作沾过边,大概率都体会过被“AI率”支配的感觉。我前阵子帮朋友改一篇投稿,内容明明是他自己写的,结果平台检测给了一个很高的AI疑似度,理由是他句子太规整、论证太顺滑,机器味太重。从那以后我开始认真研究…

作者头像 李华
网站建设 2026/9/10 9:03:53

基于Zynq的OV5640摄像头Linux驱动开发全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 9:02:47

Python为何仍是初学者最佳选择:语法生态实战全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华