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

Laravel save()/create()无法存储表单请求数据问题排查

问题描述

我编写了一个函数,逻辑为先将数据存入decision表,再把该表的ID存入survey表。规则是:若survey表中已存在对应ID则使用update()方法,否则使用save()方法。

目前遇到的问题:

  • 首次保存数据时,仅能在decision表生成ID并存入survey表,但其他请求数据未被存储;
  • 执行更新操作时,所有数据能正常存入decision表;
  • 尝试改用create()方法时,触发错误:

Illuminate\Database\Grammar::parameterize(): Argument #1 ($values) must be of type array, string given, called in C:\xampp\htdocs\xtims\vendor\laravel\framework\src\Illuminate\Database\Query\Grammars\Grammar.php on line 1022

相关代码

public function updateDecision(AssetSurvey $survey, Request $request){
        $surveyId = $request->id;
        $survey = $survey->newModelQuery()->find($surveyId);
        $surveyDecisionId = $survey->decision_id;

        if($surveyDecisionId){
            $decision = AssetSurveyDecision::where('id', $surveyDecisionId)->first();
        }
        else{
            $decision = new AssetSurveyDecision();
        }

        $decisionData = [
            'asset_decision' =>  $request->input('asset_decision'),
            'rejection_remarks' => $request->input('rejection_remarks'),
            'rejected_by' => $request->input('rejected_by'),
            'rejection_date' => $request->input('rejection_date'),
            'retraction_remarks' => $request->input('retraction_remarks'),
            'retracted_by' => $request->input('retracted_by'),
            'retraction_date' => $request->input('retraction_date')
        ];

        if($surveyDecisionId){
            $decision->update($decisionData);
        }
        else{
            $decision->save($decisionData);
        }
        
        if($decision){
            if($survey){
                $data = [
                    'decision_id' => $decision->id,
                ];
                $survey->update($data);
            }
            return response()->json($survey);
        }
    }

请求数据dd结果

array:23 [ // app\Http\Controllers\Api\Asset\SurveyController.php:587
  "id" => "26"
  "organization_id" => "1"
  "site_id" => "2"
  "site_name" => "reaaw"
  "client" => array:6 [
    "id" => "2"
    "uuid" => "404b329c-4bce-4785-8d2f-a64d91826916"
    "code" => "DEISD"
    "description" => "Digi Telecommunications Sdn. Bhd."
    "created_at" => "2022-11-14T02:59:14.000000Z"
    "updated_at" => "2022-11-14T02:59:14.000000Z"
  ]
  "primary_client_site_id" => "testttttt"
  "pic" => array:3 [
    "name" => "test"
    "phone" => "0145345345"
    "email" => "test@test.com"
  ]
  "coordinate" => array:2 [
    "longitude" => "14.234234"
    "latitude" => "11.34323"
  ]
  "telco_request_date" => "2023-04-12"
  "tentative_telco_rental_amount" => "231"
  "tentative_telco_rental_rate" => array:2 [
    "description" => "Quarterly"
    "id" => "2"
  ]
  "current_progress_status" => "1"
  "asset_decision" => array:2 [
    "description" => "Rejected by Management"
    "id" => "2"
  ]
  "rejection_remarks" => "test"
  "rejection_date" => "2023-04-15"
  "rejected_by" => "test"
  "isDirty" => "1"
  "hasErrors" => "0"
  "processing" => "0"
  "wasSuccessful" => "0"
  "recentlySuccessful" => "0"
  "__rememberable" => "1"
  "organization_name" => "XPERTS-HQ"
]

解决方案

核心问题分析

  1. save()方法传参错误:Laravel中,新建模型实例后调用save()不需要传入数据数组,需先为模型属性赋值再执行save(),否则数据不会被写入。
  2. asset_decision字段类型不匹配:从请求数据看,asset_decision是包含id和description的数组,但数据库表对应的字段应为字符串/数字类型,直接存入数组会触发类型错误,导致create()方法报错。

修正后的代码

public function updateDecision(AssetSurvey $survey, Request $request){
    // 查找对应的survey,增加不存在的判断
    $survey = $survey->newModelQuery()->find($request->id);
    if (!$survey) {
        return response()->json(['error' => 'Survey记录不存在'], 404);
    }

    // 处理asset_decision字段,提取需要存入数据库的值(示例取id,可根据表结构调整为description)
    $assetDecision = $request->input('asset_decision')['id'] ?? null;

    $decisionData = [
        'asset_decision' => $assetDecision,
        'rejection_remarks' => $request->input('rejection_remarks'),
        'rejected_by' => $request->input('rejected_by'),
        'rejection_date' => $request->input('rejection_date'),
        'retraction_remarks' => $request->input('retraction_remarks'),
        'retracted_by' => $request->input('retracted_by'),
        'retraction_date' => $request->input('retraction_date')
    ];

    if ($survey->decision_id) {
        // 更新已有决策记录
        $decision = AssetSurveyDecision::find($survey->decision_id);
        $decision->update($decisionData);
    } else {
        // 创建新的决策记录(需确保AssetSurveyDecision模型设置了$fillable属性)
        $decision = AssetSurveyDecision::create($decisionData);
        // 将新决策ID关联到survey
        $survey->update(['decision_id' => $decision->id]);
    }

    // 可选:加载关联的decision数据后返回,让响应更完整
    return response()->json($survey->load('decision'));
}

额外注意事项

  • 确保AssetSurveyDecision模型中设置了$fillable属性,允许批量赋值的字段,比如:
    protected $fillable = [
        'asset_decision',
        'rejection_remarks',
        'rejected_by',
        'rejection_date',
        'retraction_remarks',
        'retracted_by',
        'retraction_date'
    ];
    
  • 若asset_decision字段需要存储的是description而非id,只需把$assetDecision的取值改为$request->input('asset_decision')['description'] ?? null即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 10:37:07