使用link_to为PO(采购订单)模型的status属性赋值失败,求排查
问题分析与修复方案
你的代码有两个核心问题,导致点击链接后PO状态没有更新:
1. link_to 的 method 参数位置错误
你把 :method => :patch 放在了路由参数的哈希里,但在Rails的link_to方法中,HTTP请求方法是选项参数,需要单独放在第二个哈希里。原来的写法会把method当作普通的查询参数传递,而不是设置HTTP请求方法,导致实际发送的是默认的GET请求——而Rails的RESTful路由中,GET /po/:id对应的是show动作,根本没走到update动作,自然不会修改状态。
2. 更新参数的传递不符合Rails的强参数规范
即使请求走到了update动作,你直接传递的:status => 'closed'也不会被控制器的强参数机制接受,Rails要求更新模型的参数要嵌套在模型名称的键下(比如po: { status: 'closed' })。
修复步骤:
第一步:修正 link_to 的写法
使用RESTful路由助手更清晰,同时把method放到选项哈希中,并正确传递嵌套参数:
<%= link_to 'Close PO', po_path(@po), method: :patch, params: { po: { status: 'closed' } } %>
如果你的路由不是用resources :pos生成的,也可以用哈希写法,但要区分路由参数和选项:
<%= link_to 'Close PO', { action: :update, id: @po.id }, method: :patch, params: { po: { status: 'closed' } } %>
第二步:确保控制器允许更新status属性
打开你的PO控制器(比如PosController),检查update动作和强参数方法,确保status被允许:
def update @po = Po.find(params[:id]) if @po.update(po_params) redirect_to @po, notice: 'PO已成功关闭' else render :show # 或者根据需求渲染其他视图 end end private def po_params params.require(:po).permit(:status, # 这里加上status # 其他你需要允许更新的属性 ) end
为什么原来的代码会回到show视图?
因为你传递的action: :update作为查询参数时,Rails的路由匹配优先级是先匹配RESTful的路径规则(GET /po/:id对应show),而查询参数里的action不会覆盖路由的动作,所以实际执行的是show动作,页面自然跳回了PO详情页,状态也没有变化。
内容的提问来源于stack exchange,提问作者Coalsand
相关产品推荐
相关产品推荐

