扑克站点实现淘汰玩家时更新MongoDB状态的技术求助
解决扑克玩家淘汰状态更新的问题
看起来你的代码里有几个关键问题导致更新功能无法正常工作,我来帮你一步步修正:
1. 修正PUT路由的核心问题
你的PUT路由现在缺少玩家ID参数,而且findByIdAndUpdate的参数逻辑也不对。我们需要调整这两部分:
- 把路由路径改成
/seating/:id,这样才能获取到要淘汰的玩家唯一标识 - 明确指定更新字段为
{ inTournament: "No" },不需要从参数里动态获取这个值,因为淘汰动作就是固定把状态改成"No"
修正后的app.js路由代码:
// 先确保你已经引入并启用method-override中间件(否则PUT请求会被识别为POST) const methodOverride = require('method-override'); app.use(methodOverride('_method')); // 原有的seating GET路由保持不变 app.get("/seating", function(req, res){ Seat.find({inTournament: "Yes"}, function(err, allseats){ if(err){ console.log(err); } else { shuffle(allseats); res.render("seating", {seats: allseats}); } }); }); // 更新后的PUT路由 app.put("/seating/:id", function(req, res){ Seat.findByIdAndUpdate( req.params.id, { inTournament: "No" }, // 固定设置淘汰状态 function(err, updatedStatus){ if(err) { console.log(err); res.redirect("/seating"); // 出错时重回座位页面 } else { res.redirect("/seating"); // 更新成功后刷新页面,让玩家列表自动更新 } } ); });
2. 修正视图中的表单问题
你的表单存在两个小错误:action路径拼写缺了=,而且没有传递当前玩家的ID。我们需要把玩家的_id嵌入到表单的action路径中,这样路由才能定位到要更新的对象。
修正后的视图代码片段:
<div class ="row text-left" style="display:flex; flex-wrap: wrap;"> <div class="col-md-4 table table-bordered"> <h3 class="text-center">Table 1</h3> <ol> <% var i = 1; %> <% seats.forEach(function(seat){%> <% if(seat.player && i < perTable1){%> <li> <%= seat.player %> <!-- 修正action路径,添加当前seat的_id --> <form action="/seating/<%= seat._id %>?_method=PUT" method="POST"> <button class="btn btn-sm btn-warning" type="Submit">Eliminate</button> </form> </li> <% i++ %> <% } %> <% }); %> </ol> </div> </div>
额外注意事项
- method-override依赖:如果还没安装这个包,先运行
npm install method-override,否则?_method=PUT的转换不会生效,服务器会把请求当成普通POST处理。 - 简化循环逻辑:你原来的循环里用
seats[j].player其实没必要,直接用forEach回调里的seat.player就可以,代码更简洁易读。 - 重定向优化:原来的
res.send("Data Updated")会返回纯文本,改成res.redirect("/seating")能让页面自动刷新,用户可以直接看到淘汰后的玩家列表变化。
这样修改后,点击「Eliminate」按钮时,对应玩家的inTournament字段就会被正确更新为"No",页面也会自动刷新,该玩家会从参赛列表中消失。
内容的提问来源于stack exchange,提问作者J.Wenthur




