Redmine插件发送PATCH请求时URL参数错误求助
开发Redmine插件时PATCH请求URL参数错误问题
在开发Redmine插件时,遇到PATCH请求URL参数错误的问题:
- 路由配置的PATCH路由为
patch '/projects/:project_id/budgets/:id', to: 'budgets#update', as:'patch_budget' - 期望生成的URL格式为
/projects/test_project/budgets/14(其中test_project是项目ID),但实际生成的URL为/projects/14/budgets/14,即:project_id被错误替换为了budget的ID - 当前创建和删除功能运行正常,尝试修改表单后问题仍未解决
相关代码文件
路由配置
patch '/projects/:project_id/budgets/:id', to: 'budgets#update', as:'patch_budget' #update
_form.html.erb
<%= form_with model: budget do |f| %> <div> <%= f.label :name, "預算名稱" %><br> <%= f.text_field :name %> </div> <div> <%= f.label :description, "說明" %><br> <%= f.text_field :description %> </div> <div> <%= f.label :category, "預算類別" %><br> <%= f.text_field :category %> </div> <div> <%= f.label :quantity, "數量" %><br> <%= f.text_field :quantity %> </div> <div> <%= f.label :unit_cost, "單位成本" %><br> <%= f.text_field :unit_cost %> </div> <div> <%= f.label :issue_id, "議題" %><br> <%= f.select(:issue_id, Issue.all.collect { |i| [ i.subject, i.id] }) %> </div> <div> <%= f.submit "送出" %> </div> <% end %>
edit.html.erb
<h1>編輯預算</h1> <%= render "form", budget: @budget %> <br/> <%= link_to "回預算列表", budgets_path %>
budgets_controller.rb
class BudgetsController < ApplicationController before_action :find_project, :authorize def index @budgets = Budget.all @sum = Budget.all.sum(:total_cost).round(1) end def new @budgets = Budget.new end def create @budgets = Budget.new(budget_params) @budgets.project_id = @project.id @budgets.total_cost = @budgets.quantity * @budgets.unit_cost @budgets.created_by_id = User.current.id if @budgets.save redirect_to budgets_path, notice: "新增預算成功!" else render :new end end def edit @budget = Budget.find(params[:id]) end def update @budget = Budget.find(params[:id]) if @budget.update(budget_params) redirect_to budgets_path, notice: "修改成功!" else render :edit end end def destroy @budget = Budget.find(params[:id]) @budget.destroy if @budget redirect_to budgets_path, notice: "預算已刪除!" end def show @budget = Budget.find(params[:id]) @create_by = User.find(@budget.created_by_id) if @budget.modified_by_id != nil @modified_by = User.find(@budget.modified_by_id) end end private def find_project # @project variable must be set before calling the authorize filter @project = Project.find(params[:project_id]) end def budget_params params.require(:budget).permit(:name, :description, :category, :quantity, :unit_cost, :issue_id) end end
问题原因及解决方法
问题原因
form_with仅传入model: budget时,Rails无法自动识别嵌套路由所需的project_id参数,会错误地用budget的ID填充:project_id占位符。
解决方法
- 由于控制器中
before_action :find_project已经在edit动作中正确赋值了@project,只需修改表单的form_with调用,明确传入嵌套资源所需的参数:
<%= form_with model: [@project, budget] do |f| %>
这样Rails会根据嵌套路由规则,正确生成包含项目ID和budget ID的PATCH URL。
- 推荐使用Rails嵌套资源的路由写法,更符合惯例且不易出错:
resources :projects do resources :budgets, only: [:update, :index, :create, :destroy, :show, :edit] # 根据实际需要添加动作 end
使用嵌套资源后,可直接用project_budget_path(@project, @budget)生成正确的路由,无需手动定义PATCH路由。
内容的提问来源于stack exchange,提问作者angus
相关产品推荐
相关产品推荐

