3

I'm trying to build an app for storing recipes so that I can (eventually) build shopping lists based on recipe ingredients.

What I'm struggling with is being able to link ingredients to recipes based on their measures, i.e. a recipe could use 300 grams of flour and one pinch of salt while another recipe might use two cups of flour and one teaspoon of salt.

I've set up the DB with three tables: Recipes, Measures and Ingredients. However I'm getting stuck trying to create the basic form elements so that I can associate the unit (e.g. grams, cups or mL) and quantity (1 or 500) with the ingredient of the measure. So, how do I put the form together to allow this?

I started the form by adding a collection of check boxes for all the available ingredients, but this only allows the ingredient to be linked or not linked - there's no way that I know to also add information about elements of the joining table to be added here.

Here's the recipes_controller:

def new
  @recipe = Recipe.new

  @ingredients = Ingredient.all
end

def edit
  @recipe = Recipe.find(params[:id])
  @ingredients = Ingredient.all
end

def create
  @recipe = Recipe.new(recipe_params)

  if @recipe.save
    redirect_to @recipe
  else
    render 'new'
  end
end
...
private
  def recipe_params
    params.require(:recipe).permit(:name, :method, :category, ingredient_ids:[])
  end

And the models:

class Recipe < ApplicationRecord
  has_many :measures
  has_many :ingredients, through: :measures
  accepts_nested_attributes_for :ingredients
end

class Measure < ApplicationRecord
  belongs_to :ingredient
  belongs_to :recipe
  accepts_nested_attributes_for :ingredient
end

class Ingredient < ApplicationRecord
  has_many :measures
  has_many :recipes, through: :measures
end

And the basic Recipe form partial:

# /views/recipes/_form.html.erb
<%= form_for(@recipe) do |form| %>     
  <p>
    <%= form.label :name %><br>
    <%= form.text_field :name %>
  </p>

  <p>
    <%= form.collection_check_boxes :ingredient_ids, @ingredients, :id, :name %>
  </p>

  <p>
    <%= form.fields_for :measures do |ff| %>
      <% @ingredients.each do |ingredient| %>
        <%= ff.label :unit %>
        <%= ff.text_field :unit %> | 
        <%= ff.label :quantity %>
        <%= ff.text_field :quantity %> | 
        <%= ff.label ingredient.name %>
        <%= ff.check_box :ingredient_id %>     
        <br>
      <% end %>
    <% end %>
  </p>

  <p>
    <%= form.submit %>
  </p>

<% end %>

Thanks for your help!

Cat Burston
  • 2,833
  • 2
  • 12
  • 10

0 Answers0