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

Laravel多选下拉框更新时触发SQLSTATE[HY000]:1366整数值错误求助

解决Laravel多选下拉框更新时的SQL错误问题

嘿,我看你遇到的问题很典型——从单选改成多选后,数据库字段类型不匹配导致的错误。咱们一步步来解决:

错误原因分析

你看到的SQLSTATE[HY000]: General error: 1366 Incorrect integer value: '["1"]' for column 'operation_id'错误,是因为你的offers表中operation_id字段是单个整数类型,但现在你提交的是一个数组(比如["1"]),直接把数组赋值给单个整数字段就会报错。

而且你已经用了多对多关联($offer->operations()->attach()和sync()),这说明你应该用中间表来存储关联关系,而不是把operation_id存在offers表本身。


步骤1:移除offers表中不必要的operation_id字段(可选但推荐)

既然用了多对多关联,offers表的operation_id字段是单选时代码遗留的,现在可以删掉它(记得先备份数据)。如果暂时不想删,至少不要再往这个字段里写值。

步骤2:修改控制器的Store和Update方法

在store和update方法里,你现在还把operation_id包含在$request->only()里,这会尝试把数组写入offers表的operation_id字段,这就是错误的根源。

修改Store方法:

public function store(OfferRequest $request)
{
    // 移除only里的'operation_id'
    $offer = Offer::create($request->only('price', 'hotel_included', 'recommended_stay', 'hospitalisation', 'visible', 'doctor_id', 'hotel_id', 'price_fixed', 'currency', 'promote', 'first_picture'));

    $offer->translations()->create([
        'language_code' => env('APP_LOCAL', app()->getLocale()),
        'title' => $request->title,
        'features' => $request->features,
    ]);

    // 直接用request的operation_id数组,不用取keys(提交的operation_id[]本身就是id数组)
    $offer->operations()->attach($request->input('operation_id'));

    return redirect()->route('admin.offers.index')->with('success', 'Une nouvelle offre a été enregistrée');
}

修改Update方法:

public function update(OfferRequest $request, Offer $offer)
{
    // 同样移除only里的'operation_id'
    $offer->update($request->only('price', 'hotel_included', 'recommended_stay', 'hospitalisation', 'visible', 'doctor_id', 'hotel_id', 'price_fixed', 'currency', 'promote', 'first_picture'));

    $language = \App\Models\Language::where('language', request()->input('lang', env('APP_LANG', 'fr_FR')))->firstOrFail();
    $offer->translations()->updateOrCreate(
        ['offer_id' => $offer->id, 'language_code' => $language->language],
        $request->only('title', 'features')
    );

    // 直接用request的operation_id数组同步关联
    $offer->operations()->sync($request->input('operation_id'));

    return redirect()->route('admin.offers.index')->with('success', "L'offre a été mise à jour");
}

步骤3:修复视图中的选中逻辑

你原来的视图里选中判断逻辑混乱,合并优化成下面的写法:

<label for="operation_id" class="text-gray-700 inline-block">Opération</label>
<select class="focus:outline-none outline-none w-full px-3 py-2 border rounded {{ $errors->has('operation_id') ? 'border-red-400' : '' }} select-checkbox" name="operation_id[]" id="operation_id" multiple>
@php
    // 统一处理旧输入和编辑页面的已选数据
    $selectedIds = old('operation_id', isset($offer) ? $offer->operations->pluck('id')->toArray() : []);
@endphp
@foreach ($operations as $operation)
<option value="{{ $operation->id }}" {{ in_array($operation->id, $selectedIds) ? 'selected' : '' }}>{{ $operation->translation->name }}</option>
@endforeach
</select>
@if ($errors->has('operation_id'))
<div class="invalid-feedback">
<strong>{{ $errors->first('operation_id') }}</strong>
</div>
@endif

这样无论是创建页面(无$offer)还是编辑页面,都能正确显示选中的选项,同时处理表单验证后的旧输入。

步骤4:更新表单验证规则

在OfferRequest里,把operation_id的验证规则改成数组类型:

public function rules()
{
    return [
        // ...其他规则
        'operation_id' => 'required|array',
        'operation_id.*' => 'exists:operations,id', // 确保每个选中的id都在operations表中存在
        // ...其他规则
    ];
}

最后检查模型关联

确保你的Offer模型和Operation模型已经正确定义了多对多关联:
Offer模型:

public function operations()
{
    return $this->belongsToMany(Operation::class);
}

Operation模型:

public function offers()
{
    return $this->belongsToMany(Offer::class);
}

并且你已经创建了中间表(默认是offer_operation,包含offer_id和operation_id两个整数字段)。

做完这些修改后,你的多选下拉框应该就能正常工作了!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 22:07:28