Laravel Orchid中如何为多态关联创建表单?
Laravel Orchid 多态关联表单创建指南
先解决 morphMap 无效问题
首先检查 Relation::morphMap 的配置位置,必须放在 App\Providers\AppServiceProvider 的 boot 方法里,示例代码:
use Illuminate\Database\Eloquent\Relations\Relation; public function boot() { Relation::morphMap([ 'task' => App\Models\Task::class, 'project' => App\Models\Project::class, // 把所有需要多态关联的模型都加到这里 ]); }
如果之前数据库里已经有 action_items 数据,要确保 actionable_type 字段存的是上面的别名(比如'task'),而不是完整类名。要是存的是类名,得批量更新数据,把类名替换成对应别名,否则映射不会生效。
构建 Orchid 表单字段
在对应的 Orchid Screen 类里,需要添加两个核心字段:选择关联类型的下拉框,以及关联条目的选择/输入框,分两种场景:
场景1:简单输入 ID
适合关联模型 ID 明确的场景,直接用下拉框选类型,输入框填 ID:
use Orchid\Screen\Fields\Select; use Orchid\Screen\Fields\Input; public function layout(): array { return [ Select::make('actionable_type') ->title('关联类型') ->options([ 'task' => '任务', 'project' => '项目', // 对应 morphMap 里的别名和显示名称 ]) ->required(), Input::make('actionable_id') ->title('关联ID') ->required() ->type('number'), ]; }
保存逻辑直接用 create 或 update 即可,Laravel 会自动处理多态关联的赋值:
public function save(Request $request) { ActionItems::create($request->validate(ActionItems::rules())); return redirect()->route('platform.action-items.index'); }
场景2:动态选择关联条目(更友好)
如果想让用户直接选择关联模型的条目,不用手动输 ID,可以用 Orchid 的 Relation 字段结合依赖加载:
use Orchid\Screen\Fields\Select; use Orchid\Screen\Fields\Relation; use Illuminate\Http\Request; public function layout(): array { return [ Select::make('actionable_type') ->title('关联类型') ->options(Relation::morphMap()) ->required() ->empty('请选择关联类型'), Relation::make('actionable_id') ->title('关联条目') ->dependsOn('actionable_type', function (Relation $field, Request $request) { // 根据选中的类型获取对应的模型类 $modelClass = Relation::getMorphedModel($request->get('actionable_type')); if ($modelClass) { // 这里的'name'是模型中用于显示的字段,根据实际修改 $field->fromModel($modelClass::class, 'name'); } }) ->required(), ]; }
添加验证规则
在 ActionItems 模型里添加验证规则,确保提交的关联数据合法:
use Illuminate\Validation\Rule; public static function rules() { return [ 'actionable_type' => 'required|string|in:' . implode(',', array_keys(Relation::morphMap())), 'actionable_id' => [ 'required', function ($attribute, $value, $fail) use ($request) { $modelClass = Relation::getMorphedModel($request->actionable_type); if (!$modelClass || !$modelClass::find($value)) { $fail('所选的关联条目不存在'); } }, ], ]; }
内容的提问来源于stack exchange,提问作者lasew
相关产品推荐
相关产品推荐

