如何为filament-tree插件加载自定义多源数据?
解决Filament Tree加载多数据源(含非关联表)的方案
针对你在Laravel 9 + Filament 2.x环境下,需要用filament-tree插件加载3个非关联数据源树形数据的需求,提供以下可行方案:
方案1:创建数据库视图统一数据源(推荐)
这个方案利用数据库视图合并多表数据,让插件可以像处理单表一样正常使用,无需修改插件逻辑:
创建合并视图
执行SQL语句,将3个表的必要字段(需保证字段名一致)合并为一个视图:CREATE VIEW merged_tree_data AS SELECT id, parent_id, name, 'model1' AS source FROM model1 UNION ALL SELECT id, parent_id, name, 'model2' AS source FROM model2 UNION ALL SELECT id, parent_id, name, 'model3' AS source FROM model3;若各表字段名不一致,需提前映射,比如将Model2的
title字段转为name:SELECT id, parent_id, title AS name, 'model2' AS source FROM model2创建关联视图的Eloquent模型
新建模型关联这个视图,并引入filament-tree的HasTreetrait:namespace App\Models; use Illuminate\Database\Eloquent\Model; use SolutionForest\FilamentTree\Traits\HasTree; class MergedTreeData extends Model { use HasTree; protected $table = 'merged_tree_data'; public $timestamps = false; // 视图无需时间戳 // 配置树形结构字段(按插件要求) protected $treeColumnConfig = [ 'parent_id' => 'parent_id', 'title' => 'name', ]; }创建Filament Tree资源
按照插件常规流程,基于MergedTreeData模型创建Tree Resource,即可直接加载合并后的树形数据。
方案2:重写Tree Resource的数据源方法
如果不想创建数据库视图,可以在Tree Resource中重写数据源获取逻辑,手动合并数据并构建树形结构:
use SolutionForest\FilamentTree\Resources\TreeResource; use Illuminate\Support\Collection; class CustomTreeResource extends TreeResource { // 插件要求的基础配置(模型、表单、表格等) protected static ?string $model = \App\Models\Model1::class; // 随便填一个模型,实际数据源自定义 protected static function getTreeQuery() { // 从三个数据源获取数据,统一字段名 $data1 = \App\Models\Model1::select('id', 'parent_id', 'name')->get(); $data2 = \App\Models\Model2::select('id', 'parent_id', 'title as name')->get(); $data3 = \App\Models\Model3::select('id', 'parent_id', 'label as name')->get(); // 合并数据 $mergedData = $data1->merge($data2)->merge($data3); // 转换为树形结构 return collect(self::buildTree($mergedData)); } // 辅助方法:扁平集合转树形结构 private static function buildTree(Collection $items, $parentId = null) { return $items->where('parent_id', $parentId)->map(function ($item) use ($items) { $children = self::buildTree($items, $item->id); if ($children->isNotEmpty()) { $item->children = $children; } return $item; }); } }
注意:部分插件版本可能要求返回查询构建器,若出现兼容性问题,可尝试将合并后的集合转为Illuminate\Database\Eloquent\Collection,或调整插件源码中获取数据的逻辑。
方案3:自定义Tree组件数据源
若上述方案不适用,可直接在Tree组件中指定自定义数据源:
public static function tree(): Tree { return parent::tree() ->query(fn () => self::getCustomTreeData()); } private static function getCustomTreeData() { // 合并并构建树形数据的逻辑同方案2 $data1 = \App\Models\Model1::select('id', 'parent_id', 'name')->get(); $data2 = \App\Models\Model2::select('id', 'parent_id', 'title as name')->get(); $data3 = \App\Models\Model3::select('id', 'parent_id', 'label as name')->get(); $merged = $data1->merge($data2)->merge($data3); return self::buildTree($merged); }
内容的提问来源于stack exchange,提问作者Petro Gromovo
相关产品推荐
相关产品推荐

