Home > OS >  Wrong action called when using Partial
Wrong action called when using Partial

Time:11-04

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). app routes

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| %>
...
  • Related