Filament 提供了多种在应用中管理关系的方式。你应该使用哪个功能取决于你正在管理的关系类型,以及你正在寻找的用户界面。
它们兼容 HasMany,HasManyThrough,BelongsToMany,MorphMany 和 MorphToMany 关系。
关系管理器 是交互式表格,允许管理员列出、创建、附加、关联、编辑、分离、解除关联和删除相关记录,而无需离开资源的编辑或查看页面。
这些与 BelongsTo, MorphTo 和 BelongsToMany 关系兼容.
使用 选择框,用户将能够从现有记录列表中进行选择。您也可以 添加一个按钮,允许您在模态框内创建新记录,无需离开当前页面。
当 BelongsToMany 关系配合选择器使用时,你将能够选择多个选项,而不仅仅是一个。当你提交表单时,记录将自动添加到你的数据透视表。如果你愿意,你可以用一个简单的复选框列表替换掉多选下拉菜单。这两种组件的工作方式相同。
这些与 HasMany 和 MorphMany 关系兼容。
中继器 是标准表单组件, 它们可以无限地渲染一组可重复的字段. 它们可以与关系关联, 这样记录就可以从相关表中自动读取、创建、更新和删除. 它们存在于主表单 schema 中, 并可以在资源页面中使用, 以及嵌套在动作模态框中.
从用户体验(UX)的角度来看,该解决方案仅在您的关联模型只有少数几个字段的情况下才适用。否则,表单可能会变得非常长。
它们兼容 BelongsTo、HasOne 和 MorphOne 关系。
所有布局表单组件(网格, 节, 字段集, 等)都有一个 relationship() 方法。当你使用它时,该布局中的所有字段都会保存到相关模型,而不是所有者模型:
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Components\Fieldset;
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 titleCategoryResource 是所有者(父级)模型的资源类的名称。posts 是你想要管理的关系的名称。title 是将用于识别帖子的属性的名称。这将创建一个 CategoryResource/RelationManagers/PostsRelationManager.php 文件。它包含一个类,你可以在其中定义一个 表单 和 表格 用于你的关联管理器:
use Filament\Forms;
use Filament\Schemas\Schema;
use Filament\Tables;
use Filament\Tables\Table;
public function form(Schema $schema): Schema
{
return $schema
->components([
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,
];
}一旦为关系管理器定义了表格和表单,请访问您的资源的编辑或查看页面以查看其实际效果。
如果你向从 getRelations() 返回的数组传递一个键,它将在多个关系管理器之间切换时,被用于该关系管理器的 URL 中。例如,你可以传递 posts 以便在 URL 中使用 ?relation=posts,而不是数字数组索引:
public static function getRelations(): array
{
return [
'posts' => RelationManagers\PostsRelationManager::class,
];
}关联管理器通常显示在资源的“编辑”或“查看”页面上。在“查看”页面上,Filament 会自动隐藏所有修改关系的动作,例如创建、编辑和删除。我们称之为“只读模式”,默认情况下存在,以保留“查看”页面的只读行为。但是,您可以通过重写关联管理器类中的 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您可以了解更多关于软删除的信息此处。
相关记录将在一个表格中列出。整个关联管理器都围绕此表格构建,其中包含用于创建、编辑、附加/分离、关联/取消关联以及删除记录的操作。
您可以使用 表格构建器 的任何功能来定制关系管理器。
对于 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\Schemas\Schema;
public function form(Schema $schema): Schema
{
return $schema
->components([
Forms\Components\TextInput::make('name')->required(),
Forms\Components\TextInput::make('role')->required(),
// ...
]);
}请确保任何枢轴属性都列在关系的 withPivot() 方法中 和 反向关系中。
创建操作了解如何自定义 CreateAction,包括修改表单数据、更改通知以及添加生命周期钩子,请参阅 Actions 文档。
对于 BelongsToMany 和 MorphToMany 关系,您也可以编辑中间表属性。例如,如果您的 UserResource 有一个 TeamsRelationManager,并且您想将 role 中间表属性添加到编辑表单中,您可以使用:
use Filament\Forms;
use Filament\Schemas\Schema;
public function form(Schema $schema): Schema
{
return $schema
->components([
Forms\Components\TextInput::make('name')->required(),
Forms\Components\TextInput::make('role')->required(),
// ...
]);
}请确保任何枢轴属性都已在关系的 withPivot() 方法以及反向关系中列出.
EditAction要了解如何自定义 EditAction, 包括修改表单数据, 更改通知, 和添加生命周期钩子, 请参阅Actions 文档.
Filament 能够附加和分离 BelongsToMany 和 MorphToMany 关系的记录。
在生成关系管理器时,您可以传递 --attach 标志,以将 AttachAction、DetachAction 和 DetachBulkAction 也添加到表中:
php artisan make:filament-relation-manager CategoryResource posts title --attach或者,如果你已经生成了你的资源,你只需将这些操作添加到 $table 数组中即可:
use Filament\Actions\AttachAction;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\DetachAction;
use Filament\Actions\DetachBulkAction;
use Filament\Tables\Table;
public function table(Table $table): Table
{
return $table
->columns([
// ...
])
->headerActions([
// ...
AttachAction::make(),
])
->recordActions([
// ...
DetachAction::make(),
])
->toolbarActions([
BulkActionGroup::make([
// ...
DetachBulkAction::make(),
]),
]);
}默认情况下,当您搜索要附加的记录时,选项将通过 AJAX 从数据库加载。如果您希望改为在表单首次加载时预加载这些选项,您可以使用 AttachAction 的 preloadRecordSelect() 方法:
use Filament\Actions\AttachAction;
AttachAction::make()
->preloadRecordSelect()当你使用 Attach 按钮附加记录时,你可能希望定义一个自定义表单,以便向关系中添加中间表属性:
use Filament\Actions\AttachAction;
use Filament\Forms;
AttachAction::make()
->schema(fn (AttachAction $action): array => [
$action->getRecordSelect(),
Forms\Components\TextInput::make('role')->required(),
])在此示例中,$action->getRecordSelect() 返回选择字段,以选择要附加的记录。role 文本输入随后保存到中间表的 role 列。
请确保任何透视属性都列在关联的 withPivot() 方法 以及 反向关联中。
你可能想要限定 AttachAction 可用的选项:
use Filament\Actions\AttachAction;
use Illuminate\Database\Eloquent\Builder;
AttachAction::make()
->recordSelectOptionsQuery(fn (Builder $query) => $query->whereBelongsTo(auth()->user()))默认情况下,可用于 AttachAction 的选项将在表的 recordTitleAttribute() 中进行搜索。如果您希望跨多列搜索,可以使用 recordSelectSearchColumns() 方法:
use Filament\Actions\AttachAction;
AttachAction::make()
->recordSelectSearchColumns(['title', 'description'])在 AttachAction 组件上的 multiple() 方法允许您选择多个值:
use Filament\Actions\AttachAction;
AttachAction::make()
->multiple()您可以自定义在附件过程中使用的选择字段对象通过向 recordSelect() 方法传递一个函数:
use Filament\Actions\AttachAction;
use Filament\Forms\Components\Select;
AttachAction::make()
->recordSelect(
fn (Select $select) => $select->placeholder('Select a post'),
)默认情况下,您将不允许多次附加记录。这是因为您还必须在中间表上设置一个主 id 列才能使此功能正常工作。
请确保将 id 属性列在关联的 withPivot() 方法和 反向关联中。
最后,将 allowDuplicates() 方法添加到表格中:
public function table(Table $table): Table
{
return $table
->allowDuplicates();
}默认情况下,DetachBulkAction 会将所有 Eloquent 记录加载到内存中,然后逐一遍历并分离它们。
如果您正在分离大量记录,您可能希望使用 chunkSelectedRecords() 方法一次获取较少数量的记录。这将减少应用程序的内存使用:
use Filament\Actions\DetachBulkAction;
DetachBulkAction::make()
->chunkSelectedRecords(250)Filament 在分离 Eloquent 记录之前将其加载到内存中,原因有二:
authorizeIndividualRecords('delete'))。deleting 和 deleted 事件。如果您不需要独立记录策略授权和模型事件,您可以使用 fetchSelectedRecords(false) 方法,它不会在分离记录之前将其加载到内存中,而是会通过单个查询来分离它们:
use Filament\Actions\DetachBulkAction;
DetachBulkAction::make()
->fetchSelectedRecords(false)Filament 能够关联和解除关联 HasMany 和 MorphMany 关系的记录。
在生成关系管理器时,你可以传递 --associate 标志以便也向表格中添加 AssociateAction、DissociateAction 和 DissociateBulkAction:
php artisan make:filament-relation-manager CategoryResource posts title --associate或者,如果你已经生成了你的资源,你只需将这些操作添加到 $table 数组中:
use Filament\Actions\AssociateAction;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\DissociateAction;
use Filament\Actions\DissociateBulkAction;
use Filament\Tables\Table;
public function table(Table $table): Table
{
return $table
->columns([
// ...
])
->headerActions([
// ...
AssociateAction::make(),
])
->recordActions([
// ...
DissociateAction::make(),
])
->toolbarActions([
BulkActionGroup::make([
// ...
DissociateBulkAction::make(),
]),
]);
}默认情况下,当您搜索要关联的记录时,选项将通过 AJAX 从数据库加载。如果您希望在表单首次加载时预加载这些选项,您可以使用 AssociateAction 的 preloadRecordSelect() 方法:
use Filament\Actions\AssociateAction;
AssociateAction::make()
->preloadRecordSelect()您可能需要限定可用于 AssociateAction 的选项范围:
use Filament\Actions\AssociateAction;
use Illuminate\Database\Eloquent\Builder;
AssociateAction::make()
->recordSelectOptionsQuery(fn (Builder $query) => $query->whereBelongsTo(auth()->user()))默认情况下,可供 AssociateAction 使用的选项将在表的 recordTitleAttribute() 中进行搜索。如果您希望跨多列进行搜索,可以使用 recordSelectSearchColumns() 方法:
use Filament\Actions\AssociateAction;
AssociateAction::make()
->recordSelectSearchColumns(['title', 'description'])该 multiple() 方法 在 该 AssociateAction 组件 允许 您 来 选择 多个 值:
use Filament\Actions\AssociateAction;
AssociateAction::make()
->multiple()您可以自定义在关联期间使用的 select 字段对象,通过向 recordSelect() 方法传递一个函数:
use Filament\Actions\AssociateAction;
use Filament\Forms\Components\Select;
AssociateAction::make()
->recordSelect(
fn (Select $select) => $select->placeholder('Select a post'),
)默认情况下,DissociateBulkAction 会将所有 Eloquent 记录加载到内存中,然后遍历这些记录并逐个解除关联。
如果您正在解除关联大量记录,您可能希望使用 chunkSelectedRecords() 方法来每次获取少量记录。这将减少您应用程序的内存使用量:
use Filament\Actions\DissociateBulkAction;
DissociateBulkAction::make()
->chunkSelectedRecords(250)Filament 在将 Eloquent 记录分离之前,会先将它们加载到内存中,原因有二:
authorizeIndividualRecords('update'),例如)。updating 和 updated 事件。如果您不需要单个记录策略授权和模型事件,您可以使用 fetchSelectedRecords(false) 方法,该方法将不会在解除关联记录之前将它们加载到内存中,而是通过单个查询解除它们的关联:
use Filament\Actions\DissociateBulkAction;
DissociateBulkAction::make()
->fetchSelectedRecords(false)在生成您的关系管理器时,您可以传递 --view 标志,以同时向表中添加一个 ViewAction:
php artisan make:filament-relation-manager CategoryResource posts title --view或者,如果你已经生成了你的关联管理器,你只需将 ViewAction 添加到 $table->recordActions() 数组中即可:
use Filament\Actions\ViewAction;
use Filament\Tables\Table;
public function table(Table $table): Table
{
return $table
->columns([
// ...
])
->recordActions([
ViewAction::make(),
// ...
]);
}默认情况下,您将无法在关系管理器中操作已删除记录。如果您想在关系管理器中添加恢复、强制删除和筛选被软删除记录的功能,请在生成关系管理器时使用 --soft-deletes 标志:
php artisan make:filament-relation-manager CategoryResource posts title --soft-deletes或者,您可以为现有的关系管理器添加软删除功能:
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 function table(Table $table): Table
{
return $table
->modifyQueryUsing(fn (Builder $query) => $query->withoutGlobalScopes([
SoftDeletingScope::class,
]))
->columns([
// ...
])
->filters([
TrashedFilter::make(),
// ...
])
->recordActions([
DeleteAction::make(),
ForceDeleteAction::make(),
RestoreAction::make(),
// ...
])
->toolbarActions([
BulkActionGroup::make([
DeleteBulkAction::make(),
ForceDeleteBulkAction::make(),
RestoreBulkAction::make(),
// ...
]),
]);
}DeleteAction了解如何自定义 DeleteAction,包括更改通知和添加生命周期钩子,请参阅 操作文档。
ImportAction 可以添加到关系管理器的头部以导入记录。在这种情况下,您可能需要告诉导入器这些新记录属于哪个所有者。您可以使用导入选项来传递所有者记录的ID:
ImportAction::make()
->importer(ProductImporter::class)
->options(['categoryId' => $this->getOwnerRecord()->getKey()])现在,在导入器类中,你可以将所有者以一对多关系与导入的记录关联起来:
public function resolveRecord(): ?Product
{
$product = Product::firstOrNew([
'sku' => $this->data['sku'],
]);
$product->category()->associate($this->options['categoryId']);
return $product;
}或者,你可以使用导入器的 afterSave() 钩子,以多对多关系关联记录:
protected function afterSave(): void
{
$this->record->categories()->syncWithoutDetaching([$this->options['categoryId']]);
}关系管理器是 Livewire 组件. 当它们首次加载时, 拥有者记录 (作为父级的 Eloquent 记录 - 主要资源模型) 会被保存到一个属性中. 你可以使用以下方式读取此属性:
$this->getOwnerRecord()然而,如果你在一个 static 方法中,例如 form() 或 table(),$this 是不可访问的。因此,你可以使用回调函数来访问 $livewire 实例:
use Filament\Forms;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Schemas\Schema;
public function form(Schema $schema): Schema
{
return $schema
->components([
Forms\Components\Select::make('store_id')
->options(function (RelationManager $livewire): array {
return $livewire->getOwnerRecord()->stores()
->pluck('name', 'id')
->toArray();
}),
// ...
]);
}Filament 中的所有方法都接受一个回调函数,你可以在其中访问 $livewire->ownerRecord。
您可以选择将关联管理器组合到一个选项卡中. 为此, 您可以将多个管理器包裹在一个 RelationGroup 对象中, 并带有一个标签:
use Filament\Resources\RelationManagers\RelationGroup;
public static function getRelations(): array
{
return [
// ...
RelationGroup::make('Contacts', [
RelationManagers\IndividualsRelationManager::class,
RelationManagers\OrganizationsRelationManager::class,
]),
// ...
];
}默认情况下, 关联管理器将可见如果用于相关模型策略的 viewAny() 方法返回 true。
你可以使用 canViewForRecord() 方法来确定关联管理器是否应针对特定的拥有者记录和页面可见:
use Illuminate\Database\Eloquent\Model;
public static function canViewForRecord(Model $ownerRecord, string $pageClass): bool
{
return $ownerRecord->status === Status::Draft;
}在 Edit 或 View 页面类中,覆盖 hasCombinedRelationManagerTabsWithContent() 方法:
public function hasCombinedRelationManagerTabsWithContent(): bool
{
return true;
}在编辑或查看页面类中,重写 getContentTabComponent() 方法,并使用任何 选项卡 自定义方法:
use Filament\Schemas\Components\Tabs\Tab;
public function getContentTabComponent(): Tab
{
return Tab::make('Settings')
->icon('heroicon-m-cog');
}默认情况下,表单选项卡会在关系选项卡之前被渲染。要将其在之后渲染,你可以在编辑或查看页面类中覆盖 getContentTabPosition() 方法:
use Filament\Resources\Pages\Enums\ContentTabPosition;
public function getContentTabPosition(): ?ContentTabPosition
{
return ContentTabPosition::After;
}要自定义关系管理器的选项卡,请覆盖 getTabComponent() 方法,并使用任何 Tab 自定义方法:
use Filament\Schemas\Components\Tabs\Tab;
use Illuminate\Database\Eloquent\Model;
public static function getTabComponent(Model $ownerRecord, string $pageClass): Tab
{
return Tab::make('Blog posts')
->badge($ownerRecord->posts()->count())
->badgeColor('info')
->badgeTooltip('The number of posts in this category')
->icon('heroicon-m-document-text');
}如果您正在使用关系组,您可以使用 tab() 方法:
use Filament\Resources\RelationManagers\RelationGroup;
use Filament\Schemas\Components\Tabs\Tab;
use Illuminate\Database\Eloquent\Model;
RelationGroup::make('Contacts', [
// ...
])
->tab(fn (Model $ownerRecord): Tab => Tab::make('Blog posts')
->badge($ownerRecord->posts()->count())
->badgeColor('info')
->badgeTooltip('The number of posts in this category')
->icon('heroicon-m-document-text'));你可能会决定,希望资源的表单和表格与关系管理器的保持一致,并且随后想要重用你之前编写的代码。这很容易,只需从关系管理器中调用资源的 form() 和 table() 方法即可:
use App\Filament\Resources\Blog\Posts\PostResource;
use Filament\Schemas\Schema;
use Filament\Tables\Table;
public function form(Schema $schema): Schema
{
return PostResource::form($schema);
}
public function table(Table $table): Table
{
return PostResource::table($table);
}如果您正在将资源中的表单组件共享给关系管理器,您可能希望在关系管理器上隐藏它。当您想要隐藏关系管理器中所有者记录的 Select 字段时,这尤其有用,因为 Filament 无论如何都会为您处理。为此,您可以使用 hiddenOn() 方法,并传入关系管理器的名称:
use App\Filament\Resources\Blog\Posts\PostResource\RelationManagers\CommentsRelationManager;
use Filament\Forms\Components\Select;
Select::make('post_id')
->relationship('post', 'title')
->hiddenOn(CommentsRelationManager::class)如果您正在与关系管理器共享来自资源的表列,您可能希望在关系管理器上隐藏它。当您想在关系管理器中为所有者记录隐藏列时,这尤其有用,因为当所有者记录已列在关系管理器上方时,这样做是不合适的。为此,您可以使用 hiddenOn() 方法,并传入关系管理器的名称:
use App\Filament\Resources\Blog\Posts\PostResource\RelationManagers\CommentsRelationManager;
use Filament\Tables\Columns\TextColumn;
TextColumn::make('post.title')
->hiddenOn(CommentsRelationManager::class)如果您正在与关系管理器共享来自资源的表格筛选器,您可能希望在关系管理器上隐藏它。这在您希望在关系管理器中隐藏所有者记录的筛选器时特别有用,因为当表格已通过所有者记录进行筛选时,这样做并不合适。为此,您可以使用 hiddenOn() 方法,传入关系管理器的名称:
use App\Filament\Resources\Blog\Posts\PostResource\RelationManagers\CommentsRelationManager;
use Filament\Tables\Filters\SelectFilter;
SelectFilter::make('post')
->relationship('post', 'title')
->hiddenOn(CommentsRelationManager::class)您在资源内部所做的任何配置都可以在关系管理器上被覆盖。 例如,如果您想在关系管理器的继承表上禁用分页,但不是资源本身:
use App\Filament\Resources\Blog\Posts\PostResource;
use Filament\Tables\Table;
public function table(Table $table): Table
{
return PostResource::table($table)
->paginated(false);
}在关系管理器上提供额外配置可能也很有用,如果你想添加一个头部操作来创建、附加或关联关系管理器中的记录:
use App\Filament\Resources\Blog\Posts\PostResource;
use Filament\Actions\AttachAction;
use Filament\Actions\CreateAction;
use Filament\Tables\Table;
public function table(Table $table): Table
{
return PostResource::table($table)
->headerActions([
CreateAction::make(),
AttachAction::make(),
]);
}您可以应用自己的查询约束或 模型作用域 来影响整个关系管理器。为此,您可以向表的 modifyQueryUsing() 方法传递一个函数,在该函数内部您可以自定义查询:
use Filament\Tables;
use Illuminate\Database\Eloquent\Builder;
public function table(Table $table): Table
{
return $table
->modifyQueryUsing(fn (Builder $query) => $query->where('is_active', true))
->columns([
// ...
]);
}要设置关系管理器的标题,你可以使用关系管理器类上的 $title 属性:
protected static ?string $title = 'Posts';要动态设置关系管理器的标题,你可以在关系管理器类上重写 getTitle() 方法:
use Illuminate\Database\Eloquent\Model;
public static function getTitle(Model $ownerRecord, string $pageClass): string
{
return __('relation-managers.posts.title');
}标题将反映在表格标题中,以及关系管理器选项卡(如果有多个的话)。如果您想独立自定义表格标题,您仍然可以使用$table->heading()方法:
use Filament\Tables;
public function table(Table $table): Table
{
return $table
->heading('Posts')
->columns([
// ...
]);
}关联管理器使用“记录标题属性”的概念来确定关联模型的哪个属性应该用于标识它。创建关联管理器时,此属性作为第三个参数传递给 make:filament-relation-manager 命令:
php artisan make:filament-relation-manager CategoryResource posts title在此示例中,Post 模型的 title 属性将用于在关系管理器中识别一个帖子。
这主要由操作类使用。 例如,当你附加或关联一个记录, 标题将会在选择字段中列出。 当你编辑, 查看或删除一个记录, 标题将用于模态框的头部。
在某些情况下,你可能希望将多个属性连接起来以形成标题。 你可以通过用 recordTitle() 替换 recordTitleAttribute() 配置方法,并传入一个将模型转换为标题的函数来做到这一点:
use App\Models\Post;
use Filament\Tables\Table;
public function table(Table $table): Table
{
return $table
->recordTitle(fn (Post $record): string => "{$record->title} ({$record->id})")
->columns([
// ...
]);
}如果您正在使用 recordTitle(),并且您有一个关联操作或附加操作,您还需要为这些操作指定搜索列:
use Filament\Actions\AssociateAction;
use Filament\Actions\AttachAction;
AssociateAction::make()
->recordSelectSearchColumns(['title', 'id']);
AttachAction::make()
->recordSelectSearchColumns(['title', 'id'])使用 ManageRelatedRecords 页面是使用关系管理器的一种替代方案,如果您希望将管理关系的功能与编辑或查看所有者记录的功能分开。
此功能非常适合您使用资源子导航,因为您可以轻松地在查看或编辑页面与关联页面之间切换。
要创建关系页面,您应该使用 make:filament-page 命令:
php artisan make:filament-page ManageCustomerAddresses --resource=CustomerResource --type=ManageRelatedRecords当你运行此命令时,你会被问到一系列问题以自定义该页面,例如,关系的名称及其 title 属性。
您必须在您的资源的 getPages() 方法中注册此新页面:
public static function getPages(): array
{
return [
'index' => Pages\ListCustomers::route('/'),
'create' => Pages\CreateCustomer::route('/create'),
'view' => Pages\ViewCustomer::route('/{record}'),
'edit' => Pages\EditCustomer::route('/{record}/edit'),
'addresses' => Pages\ManageCustomerAddresses::route('/{record}/addresses'),
];
}当使用关系页面时,您无需使用 make:filament-relation-manager 生成关系管理器,也无需将其注册到资源的 getRelations() 方法中。
现在,你可以自定义页面,其方式与关系管理器完全相同,使用相同的 table() 和 form()。
如果你正在使用资源子导航,你可以像往常一样在资源的getRecordSubNavigation()中注册此页面:
use App\Filament\Resources\Customers\Pages;
use Filament\Resources\Pages\Page;
public static function getRecordSubNavigation(Page $page): array
{
return $page->generateNavigationItems([
// ...
Pages\ManageCustomerAddresses::class,
]);
}当在资源中注册关系管理器时,你可以使用 make() 方法向其传递一个 Livewire 属性 数组:
use App\Filament\Resources\Blog\Posts\PostResource\RelationManagers\CommentsRelationManager;
public static function getRelations(): array
{
return [
CommentsRelationManager::make([
'status' => 'approved',
]),
];
}这一属性数组映射到关系管理器类上的Livewire 公有属性:
use Filament\Resources\RelationManagers\RelationManager;
class CommentsRelationManager extends RelationManager
{
public string $status;
// ...
}现在,你可以访问关系管理器类中的 status 使用 $this->status。
默认情况下,关系管理器是惰性加载的. 这意味着它们只会在页面上可见时才会被加载。
要禁用此行为,您可以覆盖关系管理器类上的$isLazy属性:
protected static bool $isLazy = false;