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!