Laravel表单提交未触发store()方法,页面无错误重载
Laravel 10 行程阶段创建功能故障:控制器store方法未执行
问题现象
开发Laravel 10应用时,实现用户为行程添加阶段的功能出现异常:提交travel/show.blade.php中的创建新阶段表单后,页面仅重载,但数据库stages表无新条目生成;控制器的store()方法未触发(未看到方法内dd()的输出),页面无任何可见错误提示。
上下文代码
Blade表单(show.blade.php)
<form action="{{ route('user.stages.store', $travel->slug) }}" method="POST" class="add_stage_form w-100 d-none py-3"> @csrf <input type="hidden" name="travel_id" value="{{ $travel->id }}"> <div class="input_wrapper mb-1 row"> <label for="place" class="input_label">{{ __('Tappa') }}</label> <div class="col-md-6"> <input id="place" type="text" class="form-control @error('place') is-invalid @enderror" name="place" value="{{ old('place') }}" required autocomplete="place" autofocus> @error('place') <span class="invalid-feedback" role="alert"> <strong>{{ $message }}</strong> </span> @enderror </div> </div> <div class="input_wrapper mb-3 row"> <label for="note" class="input_label">{{ __('Note') }}</label> <div class="col-md-6"> <textarea id="note" name="note" class="form-control @error('note') is-invalid @enderror" autofocus> {{ old('note') }} </textarea> @error('note') <span class="invalid-feedback" role="alert"> <strong>{{ $message }}</strong> </span> @enderror </div> </div> <div class="d-flex align-items-center gap-3"> <button type="submit" class="btn button_style btn_primary"> Salva tappa </button> <button type="button" class="close_form_btn btn button_style btn_secondary"> Elimina tappa </button> </div> </form>
控制器代码(StageController.php)
public function store(StoreStageRequest $request, Travel $travel) { // Validate $val_data = $request->validated(); // Set the travel_id $val_data['travel_id'] = $travel->id; // Create slug $slug = Str::slug($request->place, '-'); $val_data['slug'] = $slug; // Handle photo upload if present if ($request->hasFile('photo')) { $image_path = Storage::put('uploads', $request->file('photo')); $val_data['photo'] = $image_path; } // Create the stage Stage::create($val_data); dd('Store method reached', $request->all(), $travel); // Redirect to the trip's show page return redirect()->route('user.travels.show', $travel->slug)->with('message', 'New stage added!'); }
请求验证类(StoreStageRequest.php)
public function authorize(): bool { return true; } public function rules(): array { return [ 'place' => 'required|min:5|max:150', 'travel_id' => 'required|exists:travel,id', 'note' => 'nullable|max:250', 'photo' => 'nullable|image|max:2000' ]; }
已尝试操作
- 验证
web.php中POST路由配置:route::post('/travels/{travel}/stages', [StageController::class, 'store'])->name('stages.store'); - 确认表单包含CSRF令牌
- 通过浏览器开发者工具确认POST请求发送至正确URL(
http://127.0.0.1:8000/user/travels/{slug}/stages),状态码为302
故障原因分析
- 路由名称不匹配:表单中调用
route('user.stages.store'),但路由定义的名称是stages.store,缺少user前缀,导致生成的路由地址错误,请求未匹配到目标控制器方法。 - 验证规则表名错误:
travel_id的exists规则指定表名为travel,但Laravel默认Eloquent模型对应的表名是复数形式(即travels),验证失败后触发重定向,但因表单默认隐藏(d-none类),错误信息无法显示。 - 路由参数绑定可能异常:路由定义中的
{travel}参数,若Travel模型未指定使用slug作为路由键,Laravel会默认用id匹配,而表单传递的是$travel->slug,导致无法正确解析Travel实例,触发隐式模型绑定失败的重定向。 - 表单隐藏导致错误不可见:表单默认有
d-none类,即使验证失败,页面也不会显示表单及错误提示,导致误以为请求正常。
修复方案
统一路由名称:将路由定义修改为包含
user前缀的名称,与表单调用一致:Route::post('/travels/{travel}/stages', [StageController::class, 'store'])->name('user.stages.store');或调整表单中的
route()调用为route('stages.store', $travel->slug),确保名称匹配。修正验证规则的表名:将
travel_id规则中的表名改为复数travels:'travel_id' => 'required|exists:travels,id',确保路由参数绑定正确:若
Travel模型使用slug作为路由键,在模型中添加以下方法:public function getRouteKeyName() { return 'slug'; }或在路由中明确指定参数匹配字段:
Route::post('/travels/{travel:slug}/stages', [StageController::class, 'store'])->name('user.stages.store');调整表单显示逻辑:验证失败时确保表单可见,在Blade中修改表单的
class属性,根据是否有旧数据或错误来控制显示:<form action="{{ route('user.stages.store', $travel->slug) }}" method="POST" class="add_stage_form w-100 py-3 {{ (old('place') || $errors->any()) ? '' : 'd-none' }}">调试验证失败情况:临时在控制器
store()方法最开头添加dd($request->all(), $errors),或查看Laravel日志(storage/logs/laravel.log),确认是否有验证错误或其他异常。
内容的提问来源于stack exchange,提问作者user27022576
相关产品推荐
相关产品推荐

