Laravel Ajax更新用户报错No query results for model [App\User]排查修复
Hey there! Let's break down this error and fix your code step by step.
错误含义解析
这个错误提示的意思非常明确:你的控制器通过User::findOrFail($id)尝试查找ID为{id}的用户,但数据库里根本不存在这个ID的记录。本质原因是传到控制器的$id值无效——要么是空字符串、占位符,要么是数据库里没有的ID。
代码问题排查与修正方案
我们从核心问题到细节问题逐一解决:
1. 核心问题:Ajax请求的URL未传递正确的用户ID
你的Ajax请求URL写死成了http://localhost:8000/update/{user},这里的{user}是占位符,并没有替换成实际的用户ID,导致控制器收到的$id就是字符串{user},自然找不到对应的用户。
修正方法:
从表单的隐藏id字段动态获取用户ID,生成正确的URL:
// 替换原来的SITEURL定义 var userId = $('#id').val(); var SITEURL = 'http://localhost:8000/update/' + userId;
2. 请求方法不匹配
你的路由定义的是PUT请求,但Ajax里用的是type: 'post',Laravel会无法匹配到正确的路由,甚至可能导致参数传递异常。
修正方法:
把Ajax的请求类型改成PUT,和路由保持一致:
$.ajax({ url: SITEURL, type: 'PUT', // 改成PUT dataType: 'json', // ...其他参数 });
3. 按钮的data-id硬编码无效
你的支付按钮data-id="1"是固定值,不是当前用户的真实ID,即使用到这个值也会导致错误。
修正方法:
直接从表单隐藏字段拿ID(我们已经在第一步做了),或者把按钮的data-id改成动态值:
<a href="javascript:void(0)" class="btn btn-sm btn-primary float-right buy_now" data-amount="{{ $userinformations[0]->amount }}" data-id="{{ $userinformations[0]->id }}">Make Payment</a>
4. Blade视图中选中状态代码混用错误
你在Blade里混写了原生PHP和Blade语法,比如<?php if(isset($_GET['package']) == '{{ $userinformation->package }}') echo 'selected'; ?>,这种写法不仅逻辑错误,也不符合Laravel的最佳实践。
修正方法:
用Blade的原生语法处理选中状态,比如package下拉框的选项:
<select id="package" name="package" class="form-control @error('package') is-invalid @enderror" required autocomplete="package" autofocus> @foreach($userinformations as $userinformation) <option value="{{ $userinformation->package }}" {{ old('package', $userinformations[0]->package) == $userinformation->package ? 'selected' : '' }}> {{ ucfirst($userinformation->package) }} </option> @endforeach <option value="basic">Basic</option> <option value="regular">Regular</option> <option value="infinite">Infinite</option> </select>
其他下拉框(months、amount等)都可以用同样的方式修正。
5. 表单字段缺失与冗余问题
- 你的控制器里赋值了
$user->expiry_date,但Blade视图里没有对应的输入框,会导致这个字段被赋值为null,如果数据库字段不允许为空会报错,建议添加对应的输入框或者从控制器里移除这个赋值。 - Ajax请求里传了
password,但表单里没有这个字段,会传递undefined,建议删除这个冗余参数。
完整修正后的Ajax脚本示例
<script> var userId = $('#id').val(); var SITEURL = 'http://localhost:8000/update/' + userId; $.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } }); $('body').on('click', '.buy_now', function(e){ var totalAmount = $('#amount').val(); var product_id = userId; var options = { "key": "***********", "amount": (totalAmount*100), "name": "AddSpy", "description": "Payment", "image": "http://localhost:8000/frontend/images/addspy1.png", "handler": function (response){ $.ajax({ url: SITEURL, type: 'PUT', dataType: 'json', data: { razorpay_payment_id: response.razorpay_payment_id, totalAmount : totalAmount, product_id : product_id, name : $('#name').val(), phone : $('#phone').val(), email : $('#email').val(), country : $('#country').val(), state : $('#state').val(), purpose : $('#purpose').val(), package : $('#package').val(), months : $('#months').val(), quantity : $('#quantity').val(), amount : $('#amount').val(), expiry_date : $('#expiry_date').val() // 确保视图里有这个输入框 }, success: function (msg) { console.log('Update successful:', msg); // window.location.href = 'thank-you'; }, error: function(xhr) { console.error('Update failed:', xhr.responseText); } }); }, "prefill": { "contact": $('#phone').val(), "email": $('#email').val(), }, "theme": { "color": "#528FF0" } }; var rzp1 = new Razorpay(options); rzp1.open(); e.preventDefault(); }); </script>
内容的提问来源于stack exchange,提问作者ayushflitzip

