You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FilamentPHP如何在分类创建表单中实现同模型关联选择

解决方案

1. 先修正分类模型的关联定义

首先确保你的Category模型里正确定义了父子分类的关联关系:

// app/Models/Category.php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Category extends Model
{
    protected $fillable = ['id', 'slug', 'name', 'parent_id'];

    // 关联父分类
    public function parent(): BelongsTo
    {
        return $this->belongsTo(self::class, 'parent_id');
    }

    // 关联子分类(可选,用于展示层级结构)
    public function children(): HasMany
    {
        return $this->hasMany(self::class, 'parent_id');
    }
}

2. 修正Filament表单代码

你之前的表单代码存在两个核心问题:

  • 错误使用categories作为Select字段名,应该直接绑定parent_id字段
  • 关联关系未指向模型里定义的parent关联

修正后的表单代码如下:

public static function form(Form $form): Form
{
    return $form
        ->schema([
            Forms\Components\TextInput::make('name')
                ->required()
                ->maxLength(255),
            Forms\Components\TextInput::make('slug')
                ->required()
                ->maxLength(255)
                ->unique(ignoreRecord: true), // 可选:确保slug唯一,编辑时忽略当前记录
            Forms\Components\Select::make('parent_id')
                ->label('父分类')
                ->relationship('parent', 'name') // 关联模型里的parent方法,显示name字段
                ->preload() // 预加载所有分类选项
                ->searchable() // 支持搜索分类
                ->options(function (callable $get) {
                    // 编辑时排除当前分类,避免将自己设为父分类造成循环
                    $currentCategoryId = $get('id');
                    return \App\Models\Category::query()
                        ->when($currentCategoryId, fn($query) => $query->where('id', '!=', $currentCategoryId))
                        ->pluck('name', 'id');
                })
                ->placeholder('选择父分类(可选)'),
        ]);
}

关键说明

  • 移除了原本的TextInput::make('parent_id'),Select组件会直接处理parent_id的赋值
  • relationship('parent', 'name')中,第一个参数是模型里定义的关联方法名parent,第二个参数是要显示的字段name
  • 新增的options闭包用于在编辑分类时排除自身,防止出现循环引用的层级结构
  • searchable()和preload()可以提升用户选择分类的操作体验

内容的提问来源于stack exchange,提问作者Daniel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 10:40:18