管理关联
选择合适的工具
Filament 提供了许多方法用来在应用中管理关联。该使用哪个特性取决于你管理的关联类型,以及你想要使用哪种 UI。
关联管理器 - 资源表单下的交互式表格
兼容
HasMany
、HasManyThrough
、BelongsToMany
、MorphMany
和MorphToMany
关联。
关联管理器是一个允许管理员在不离开资源编辑页或者查看页的情况下,罗列、创建、编辑、删除、关联和取消关联相关记录的交互式表格。
Select & checkbox list - 从现有记录中选择或创建新记录
兼容
BelongsTo
、MorphTo
和BelongsToMany
关联。
使用 select,用户可以从现有记录列表中选择。你也可以添加按钮,使之能让你在模态框中添加新记录,而不必离开当前页面。
当在 Select 中使用 BelongsToMany
关联时,你将可以选中多个选项。记录会在你提交表单时,自动添加到透视表中。如果需要,你可以将多选下拉列表换成简单的复选项列表。两个组件的工作原理是一样的。
Repeaters - 在所有者的表单内 CRUD 多个关联记录
兼容
HasMany
和MorphMany
关联。
Repeater 是标准的表单组件,可以无限地渲染一套可重复的字段。它们可以和一个关联挂钩,这样记录旧可以从关联表中自动读取、创建、更新及删除。它们位于主表单 schema 的内部,可用在资源页的内部。也可以嵌套在 Action 模态框中。
以用户体验来说,该方案只适用于关联模型的字段有限。否则,表单可能会十分长。
布局表单组件 - 将表单字段保存到单个关联中
兼容
BelongsTo
、HasOne
和MorphOne
关联。
所有的布局组件(Grid、Section、Fieldset 等)都有一个 relationship()
方法。使用该方法时,在该布局内的所有字段会被保存到关联模型中,而非所有者的模型:
use Filament\Forms\Components\Fieldset;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
Fieldset::make('Metadata')
->relationship('metadata')
->schema([
TextInput::make('title'),
Textarea::make('description'),
FileUpload::make('image'),
])
本例中,title
、description
和 image
会自动从 metadata
关联中加载,并且在表单提交时保存。如果 metadata
记录不存在,则会自动创建。
该特性在表单文档中有更多解释。请访问该页面获取更多如何使用的信息。
创建关联管理器
使用 make:filament-relation-manager
命令,可以创建关联管理器:
php artisan make:filament-relation-manager CategoryResource posts title
CategoryResource
是(父级)模型的资源类名。posts
是你要管理的关联的名称。title
是用来识别 post 的属性名。
这个命令将会创建 CategoryResource/RelationManagers/PostsRelationManager.php
文件。它包含了一个类,让你可以为关联管理器定义表单和表格:
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Tables;
use Filament\Tables\Table;
public function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('title')->required(),
// ...
]);
}
public function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('title'),
// ...
]);
}
你必须在资源的 getRelations()
方法中注册这些新关联管理器:
public static function getRelations(): array
{
return [
RelationManagers\PostsRelationManager::class,
];
}
当完成资源管理器的表格和表单定义后,可以访问资源的编辑页或查看页,在 Action 中查看。
只读模式
关联管理器通常展示在资源的编辑或者查看页面。在查看页面上,Filament 自动隐藏所有修改关联的所有 Action,如创建、编辑及删除。我们称之为"只读模式",因为默认情况下查看页面保留了只读行为。不过,你可以在关联管理器类上重写 isReadOnly()
方法,使之始终返回 false
,来禁用该行为:
public function isReadOnly(): bool
{
return false;
}
此外,如果讨厌该功能,你可以在面板配置中一次性禁用所有关联管理器的只读功能:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->readOnlyRelationManagersOnResourceViewPagesByDefault(false);
}
非常规反转关联名
对于那些未遵循 Laravel 命名规范的反转关联,你可以在表格中使用 $inverseRelationship()
方法:
use Filament\Tables;
use Filament\Tables\Table;
public function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('title'),
// ...
])
->inverseRelationship('section'); // Since the inverse related model is `Category`, this is normally `category`, not `section`.
}
处理软删除
默认情况下,你不能在关联管理器中和已删除的数据进行交互。如果你想要在关联管理器中添加恢复数据、强制删除和过滤垃圾数据等功能,可以在生成关联管理器的时候使用 --soft-deletes
标志:
php artisan make:filament-relation-manager CategoryResource posts title --soft-deletes
查看更多软删除的相关内容,请点击此处。
展示关联记录
关联记录会在一个表格中展示。整个关联管理器都是基于这个表格,包括新建、编辑、附加/分离记录、关联/取消关联和删除记录等操作(Action)。
此外,你也可以使用表格构造器的其他所有特性,来自定义关联管理器。
使用中间属性展示列表
对于 BelongsToMany
和 MorphToMany
关联,你也可以添加中间表属性。比如,如果你的资源 UserResource
有一个关联管理器 TeamsRelationManager
,而且你想要将 role
中间属性添加到表中,你可以:
use Filament\Tables;
public function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('name'),
Tables\Columns\TextColumn::make('role'),
]);
}
请确保所有的中间属性都在关联和反向关联的 withPivot()
方法中罗列出来。
创建关联记录
使用中间属性新建记录
对于 BelongsToMany
和 MorphToMany
关联,你也可以添加中间表属性。比如,如果你的资源 UserResource
有一个关联管理器 TeamsRelationManager
,你想要在新建表单中添加 role
中间属性,你可以使用:
use Filament\Forms;
use Filament\Forms\Form;
public function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('name')->required(),
Forms\Components\TextInput::make('role')->required(),
// ...
]);
}
请确保所有的中间属性都在关联和