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

Laravel+FilamentPHP 3.x:订单编辑时TextInput无法自动加载产品价格

Laravel + FilamentPHP 3.x 订单编辑时关联产品价格不显示问题

问题场景

使用Laravel与FilamentPHP 3.x开发项目,编辑订单记录时,关联产品的价格无法自动显示在TextInput组件中。订单表与产品表为关联关系,价格字段存储于产品表内。

数据库表结构

订单表迁移代码

public function up(): void
{
    Schema::create('orders', function (Blueprint $table) {
        $table->id();
        $table->foreignIdFor(User::class);
        $table->foreignIdFor(Products::class);
        $table->string('order_code')->unique();
        $table->unsignedInteger('quantity');
        // $table->decimal('unit_price', '10', 2);
        $table->string('status')->default('pending');
        $table->timestamps();
    });
}

产品表迁移代码

public function up(): void
{
    Schema::create('products', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->string('slug')->unique();
        $table->text('description')->nullable();
        $table->string('features');
        $table->unsignedBigInteger('price');
        $table->dateTime('start_at')->nullable();
        $table->boolean('is_visible')->default(true);
        $table->boolean('is_featured')->default(false);
        $table->longText('image')->nullable();
        $table->timestamps();
    });
}

模型关联代码(Order模型)

public function products()
{
    return $this->belongsTo(Products::class);
}

OrderResource表单代码

Group::make()->schema([
    Section::make()->schema([
        Select::make('products_id')
            ->label('Product')
            ->options(Products::query()->pluck('name', 'id'))
            ->native(false)
            ->reactive()
            ->afterStateUpdated(fn ($state, Set $set) =>
            $set('price', Products::find($state)?->price ?? 0)),
        TextInput::make('quantity')
            ->numeric()
            ->default(1)
            ->required()
            ->live()
            ->dehydrated(),
        TextInput::make('price')
            ->label('Price')
            ->prefix('IDR')
            ->disabled()
            ->dehydrated()
            ->numeric()
            ->required(),
        Placeholder::make('gross_amount')
            ->label('Total Price')
            ->content(function ($get) {
                return $get('quantity') * $get('price');
            }),
    ])
])

尝试过的无效修改

给price的TextInput添加default方法:

TextInput::make('price')
    ->label('Price')
    ->prefix('IDR')
    ->disabled()
    ->dehydrated()
    ->numeric()
    ->required()
    ->default(function ($record) {
        return $record->product ? $record->product->price : 0;
    }),

问题解决步骤

1. 修正模型关联命名错误

Order模型中关联方法使用复数products(),但belongsTo关联对应单个产品,应改为单数命名,否则调用$record->product会无法匹配关联方法:

// Order模型中修改关联方法
public function product()
{
    return $this->belongsTo(Products::class);
}

2. 编辑页面初始化价格显示

default方法仅适用于创建页面,编辑页面需用state方法从关联模型读取初始价格:

TextInput::make('price')
    ->label('Price')
    ->prefix('IDR')
    ->disabled()
    ->dehydrated()
    ->numeric()
    ->required()
    ->state(function ($record) {
        return $record->product?->price ?? 0;
    });

3. 优化产品选择后的价格同步逻辑

在产品选择框的afterStateHydrated中补充初始化逻辑,确保编辑页面加载时自动同步价格:

Select::make('products_id')
    ->label('Product')
    ->options(Products::query()->pluck('name', 'id'))
    ->native(false)
    ->reactive()
    ->afterStateUpdated(fn ($state, Set $set) =>
        $set('price', Products::find($state)?->price ?? 0)
    )
    // 编辑页面加载时自动触发价格同步
    ->afterStateHydrated(fn ($state, Set $set) =>
        $set('price', Products::find($state)?->price ?? 0)
    );

关于订单表是否需要存储价格的疑问

尽管产品表已有价格字段,仍建议在订单表中存储下单时的产品价格,原因如下:

  • 数据一致性:后续产品价格修改时,历史订单需保留下单时的原始价格,避免订单金额与实际交易记录不符。
  • 查询效率:统计订单金额时无需关联产品表,直接读取订单表价格字段可提升查询性能。

你目前注释掉了订单表的unit_price字段,建议恢复该字段并在创建订单时同步存储产品价格,这样编辑订单时可直接从订单表读取价格,无需依赖关联模型。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 21:44:50