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

Laravel Nova可重复组件配置错误引发SQL列不存在异常

Laravel Nova 一对多关联保存错误分析与解决

问题场景

环境:Laravel 10 / Nova 4.27

模型关联代码

ProductAttribute模型:

class ProductAttribute extends Model
{
    protected $table = 'product_attributes';
    protected $primaryKey = 'id';
    protected $fillable = ['product_id', 'key', 'value' ];

    public function scopeGetByProductId($query, int $productId= null)
    {
        if (!empty($productId)) {
            $query->where($this->table . '.product_id', $productId);
        }
        return $query;
    }
    public function product(){
        return $this->belongsTo(Product::class, 'product_id','id');
    }
}

Product模型:

class Product extends Model implements HasMedia
{
    use Sluggable, InteractsWithMedia;
    use HasHeartbeats;

    protected $table = 'products';
    protected $primaryKey = 'id';

    public function productAttributes(): HasMany
    {
        return $this->hasMany(ProductAttribute::class);
    }
}

Nova配置操作

  1. 通过php artisan nova:repeatable ProductAttribute创建可重复组件,字段配置:
class ProductAttribute extends Repeatable
{
    public function fields(NovaRequest $request)
    {
        return [
            Text::make(__('Key'))->rules('required', 'max:255'),
            Textarea::make('Value')->rules('required', 'max:255'),
        ];
    }
}
  1. 在Product的Nova资源中添加字段:
HasMany::make(name: __('Product attributes'), attribute: 'productAttributes', resource: \App\Nova\ProductAttribute::class)->fullWidth(),

错误信息

保存时出现SQL错误:

[2024-11-22 10:51:09] local.ERROR: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'productAttributes' in 'field list' (Connection: mysql, SQL: update `product_attributes` set `productAttributes` = [{"type":"product-attribute","fields":{"key":"11","value":"11111"}}], `product_attributes`.`updated_at` = 2024-11-22 10:51:09 where `id` = 5) {"userId":1,"exception":"[object] (Illuminate\\Database\\QueryException(code: 42S22): SQLSTATE[42S22]: Column not found: 1054 Unknown column 'productAttributes' in 'field list' (Connection: mysql, SQL: update `product_attributes` set `productAttributes` = [{\"type\":\"product-attribute\",\"fields\":{\"key\":\"11\",\"value\":\"11111\"}}], `product_attributes`.`updated_at` = 2024-11-22 10:51:09 where `id` = 5) at /mnt/_work_sdb8/wwwroot/lar/NovaProducts/vendor/laravel/framework/src/Illuminate/Database/Connection.php:829)
[stacktrace]

错误原因

混淆了Nova Repeatable组件与Nova Resource的用途:

  • HasMany字段要求关联的是标准Nova Resource(对应独立的数据模型资源),但你传入的是通过nova:repeatable生成的Repeatable组件。
  • Nova错误地将Repeatable组件的序列化数据当作字段值,尝试更新productAttributes列(该列在数据库中不存在),而非处理一对多关联的product_attributes表数据。

解决方案

根据需求选择以下两种方案之一:

方案1:使用HasMany关联标准Nova Resource(适合独立管理属性)

  1. 创建ProductAttribute的Nova Resource:
php artisan nova:resource ProductAttribute
  1. 修改生成的app/Nova/ProductAttribute.php配置字段:
class ProductAttribute extends Resource
{
    public static $model = \App\Models\ProductAttribute::class;
    public static $title = 'key';
    public static $search = ['key', 'value'];

    public function fields(NovaRequest $request)
    {
        return [
            ID::make()->sortable(),
            Text::make(__('Key'))->rules('required', 'max:255'),
            Textarea::make('Value')->rules('required', 'max:255'),
            BelongsTo::make('Product'),
        ];
    }
}
  1. 保持Product Nova资源中的HasMany字段配置不变,此时Nova会正确处理一对多关联的增删改查。

方案2:使用Repeatable字段在Product页面内编辑属性(适合内嵌编辑)

  1. 删除Product Nova资源中的HasMany字段,替换为Repeatable字段:
// app/Nova/Product.php
use Laravel\Nova\Fields\Repeatable;
use App\Nova\Repeatables\ProductAttribute; // 注意路径:nova:repeatable生成的文件默认在app/Nova/Repeatables目录下

public function fields(NovaRequest $request)
{
    return [
        // 其他现有字段...
        Repeatable::make(__('Product attributes'), 'productAttributes')
            ->repeatable(ProductAttribute::class)
            ->fullWidth(),
    ];
}
  1. 确保Product模型支持关联的批量赋值:
    无需在$fillable中添加关联字段,Laravel会自动通过saveMany处理关联数据,若模型设置了$guarded,可改为:
// app/Models/Product.php
protected $guarded = [];

关键概念区分

  • HasMany字段:对应独立Nova Resource,提供关联列表、跳转编辑、批量操作,适配数据库一对多关联表结构。
  • Repeatable字段:在当前资源页面内嵌可重复字段组,适合简单嵌套数据,Nova自动处理关联数据的增删(通过saveMany)或序列化存储(若对应JSON字段)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 01:24:53