I’m trying to use Partial to render a form into Edit and Create view (to handle both actions). The problem is that it works with Create action but the form does not work for editing, it only creates. It seems that the app ignore and use create action by default (the submit button is automatically named “Create Expense” instead of “Update Expense”).
By using this kind of route, I want to edit an Expense (that is linked with a Category).
I did the navigation from Category show view to my Expense edit form view like this.
<% @category.expenses.each do |expense| %>
<tr>
<td><%= expense.name %></td>
<td>
<%= link_to "Edit", edit_category_expense_path(@category, expense) %>
</td>
</tr>
<% end %>
I’m using Partial for rendering my form into Expense edit view.
<h1>Edit Expenses</h1>
<%= render "form", expense: @expense %>
Then my form is simply like this.
<%= form_with model: [ @category, @expense] do |form| %>
<p>
<%= form.label :name %><br>
<%= form.text_field :name %>
</p>
<p>
<%= form.submit %>
</p>
<% end %>
My Expense controller
def edit
@expense = Expense.find(params[:id])
@category = @expense.category
end
def new
@expense = @category.expenses.new
end
Finally, i'm rendering the creation form in my Category show view.
<h2>Add Expense:</h2>
<%= render 'expenses/form' %>
But I got undefined method 'model_name' for nil:NilClass
when I'm trying to access to my Category show view
Solution based on @Chiperific answer
According to my project structure, I had to put @expense = Expense.new
in the show action of Category controller. That's where I displayed the form.
As for the edit form, the answer of @Chiperific explains it perfectly
Thanks
CodePudding user response:
.build
instantiates a new record. Rails recognizes that the record is new, not persisted, and automatically does what you are seeing (send the form data to the #new
action and use 'Create' for the button language.
In your controller, you need to get the existing record you want to edit:
...
def new
@expense = @category.expenses.new
end
def edit
@expense = Expense.find(params[:id])
end
And adjust your form:
<%= form_with model: [ @category, expense ] do |form| %>
...