如何在FilamentPHP的子Repeater表单中获取父级ID?
解决Filament嵌套Repeater中祖孙关系的project_id自动填充问题
针对你遇到的三层嵌套Repeater(projects -> groups -> requests)里requests表无法自动填充project_id的问题,给你两个实用的解决方案:
方案一:利用模型事件自动填充(推荐)
这个方法不需要修改表单代码,一劳永逸,不管是通过Filament表单还是其他方式创建requests,都会自动同步project_id。
在你的Request模型中添加创建事件:
protected static function booted(): void { static::creating(function (Request $request) { // 当group_id存在时,从关联的group中获取project_id if ($request->group_id) { $request->project_id = $request->group->project_id; } }); }
原理很简单:因为groups已经关联了projects(group表有project_id),所以在request创建时,直接通过关联的group拿到对应的project_id赋值即可,完全不需要在表单里手动处理。
方案二:在Filament表单中手动传递(适配编辑场景)
如果只需要在编辑项目时填充project_id,或者不想用模型事件,可以修改表单代码:
- 首先在groups的Repeater里添加一个隐藏字段,用来存储当前project的id:
Forms\Components\Repeater::make('groups')->relationship()->schema([ // 原有字段... Forms\Components\TextInput::make('project_id') ->hidden() ->default(fn ($get) => $get('../../id')), // 获取外层project的id // requests的Repeater... ])
- 然后在requests的
mutateRelationshipDataBeforeCreateUsing中从父级group获取project_id:
->mutateRelationshipDataBeforeCreateUsing(function (array $data, Get $get): array { $data['project_id'] = $get('../project_id'); return $data; })
⚠️ 注意:这个方法只在编辑已有项目时有效,新建项目时因为project还未保存,../../id返回null,所以无法获取到project_id,这时候还是得依赖方案一。
为什么你之前的$get('../../id')没用?
新建project时,这条记录还没被写入数据库,所以id字段还不存在,$get('../../id')自然拿不到值;只有在编辑已有project时,这个路径才能正确获取到project的id。
内容的提问来源于stack exchange,提问作者Selvakumar Eswaran
相关产品推荐
相关产品推荐

