Rails Forms Passing Array in Params for M to M Associaton

Edit: Essentially something like this needs to be missed:

{
  'tabled_id' : '1',
  'recipes' : [{
        { 'recipe_id' : '3',
          'quantity' : '2'
        }
        { 'recipe_id' : '5',
          'quantity' : '1'
        }
  }]
}

      

And I think what I should do params.require(:order).permit(:table_id, {recipes:, [:id,:quantity]} )

on the controller side.

I'm learning Rails while building an order system and I'm stuck trying to create a form for orders that are missing quantities. Where Orders is an embedded resource for a Restaurant.

My models look like this:

class Restaurant < ActiveRecord::Base
    has_many :orders
    has_many :recipes, dependent: :destroy
end

class Order < ActiveRecord::Base
    belongs_to :restaurant
    has_many :order_recipes, dependent: :destroy
    has_many :recipes, through: :order_recipes
end

class Recipe < ActiveRecord::Base
    belongs_to :restaurant
    has_many :order_recipes
    has_many :orders, through: :order_recipes
end

      

View:

    <%= form_for([@restaurant, @order]) do |order_form| %>
        <%= order_form.label :Table_Number %>
        <%= order_form.number_field :table_id %>

        <h3>Recipes: </h3>
        <br>

        <% @restaurant.recipes.each do |recipe| %>
            <%= order_form.fields_for :recipe, recipe do |r| %>
                <%= r.label recipe.name %>
                <%= r.hidden_field :id %>
                <%= r.number_field :quantity %>
            <% end %>
        <% end %>

        <%= order_form.submit(@order.new_record? ? "Create Order" : "Edit Order", class: "btn btn-success") %>
    <% end %>

      

This will give a form that looks correct but will not pass all parameters. Let's say I have 3 recipes. And I set their quantities to 2,3,4 respectively and table_id to 1. When I check the parameters, I see that only the last recipe with its quantity was accepted. params[:order] => {"table_id"=>"1", "recipe"=>{"id"=>"4", "quantity"=>"4"}}

I need to be able to send all recipes with assigned quantities. Also, I am using the accepted answer in this question to be able to access the count column: Rails 4 Accessing the join table attributes

+3


source to share


1 answer


When you pass fields_for :recipes

multiple times, the method fields_for

doesn't know how you are sending the array of things. Therefore, it will specify the parameters as if it were only one instance, so only the last instance will get through. You have to pass an array of recipes in fields_for

so it can specify the parameters so that rails know it's an array of things when it's picked up again ( docs ). This is because form parameters in browsers do not support nesting by default. The actual parameters are flat key parameters. Rails has several naming conventions about how parameters can be named, so they will automatically be forced to be bound to an array.



<%= form_for([@restaurant, @order]) do |order_form| %>
    <%= order_form.label :Table_Number %>
    <%= order_form.number_field :table_id %>

    <h3>Recipes: </h3>
    <br>


    <%= order_form.fields_for :recipes, @restaurant.recipes do |r| %>
      <%= r.label recipe.name %>
      <%= r.hidden_field :id %>
      <%= r.number_field :quantity %>
    <% end %>


    <%= order_form.submit(@order.new_record? ? "Create Order" : "Edit Order", class: "btn btn-success") %>
<% end %>

      

+1


source







All Articles