3

Edit: Essentially looking to pass something like this:

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

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

I'm learning Rails building an ordering system and I'm stuck trying to build a form for Orders that passes quantity. Where Orders is a nested resource for 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 yield a form that looks correct, but won't pass all parameters. Let's say I have 3 recipes. And I set their quantities to 2,3,4 respectively, and the table_id to 1. When I inspect the parameters, I see that only the last recipe with its quantity has been passed. params[:order] => {"table_id"=>"1", "recipe"=>{"id"=>"4", "quantity"=>"4"}} I need to be able to send all recipes with their assigned quantities. Also, I'm using the accepted answer in this question to be able to access the quantity column: Rails 4 Accessing Join Table Attributes

Community
  • 1
  • 1
Patricio Jerí
  • 528
  • 2
  • 5
  • 15

1 Answers1

1

When you hand in fields_for :recipes multiple times, the fields_for method is not aware of you sending an array of things. Therefore it will name the parameters as if it was only one instance, so only the last instance will come through. You have to hand in the array of recipes to the fields_for, so it can name the parameters, so that rails knows it is an array of things when it gets picked up again (docs). This is because form parameters in browsers do not support nesting by default. The actual parameters are flat key-value paramters. Rails has some naming conventions on how paramters can be named, so they will automatically be coerced 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 %>
smallbutton
  • 3,377
  • 15
  • 27