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" ]
解决方案
核心问题分析
save()方法传参错误:Laravel中,新建模型实例后调用save()不需要传入数据数组,需先为模型属性赋值再执行save(),否则数据不会被写入。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
相关产品推荐
相关产品推荐

