You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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占位符。

解决方法

  1. 由于控制器中before_action :find_project已经在edit动作中正确赋值了@project,只需修改表单的form_with调用,明确传入嵌套资源所需的参数:
<%= form_with model: [@project, budget] do |f| %>

这样Rails会根据嵌套路由规则,正确生成包含项目ID和budget ID的PATCH URL。

  1. 推荐使用Rails嵌套资源的路由写法,更符合惯例且不易出错:
resources :projects do
  resources :budgets, only: [:update, :index, :create, :destroy, :show, :edit] # 根据实际需要添加动作
end

使用嵌套资源后,可直接用project_budget_path(@project, @budget)生成正确的路由,无需手动定义PATCH路由。

内容的提问来源于stack exchange,提问作者angus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 13:40:25