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.
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