ruby-on-railserbredmine

incorrect url when send patch method in redmine plugin


My route :

patch '/projects/:project_id/budgets/:id', to: 'budgets#update', as:'patch_budget' #update

when i send a patch method to this route, :project_id should be my project_id, like:

/projects/test_project/budgets/14

but it turns to budget.id, like:

/projects/14/budgets/14

_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

Create and delete are running normally, I try many ways in my form, but it didn't work, thanks for the help.


Solution

  • You need to pass an array to generate nested routes:

    <%= render "form", budget: @budget, project: @project  %>
    
    <%= form_with model: [project, budget] do |f| %>
    

    See https://api.rubyonrails.org/v7.0/classes/ActionDispatch/Routing/PolymorphicRoutes.html