kid_drew
kid_drew

Reputation: 3995

Rails association conundrum

I'm creating a service to store food recipes, and I'm trying to create a list of ingredients with optional preferred brands for each ingredient. So, for example, I might say that a pasta recipe uses peeled tomatoes and the preferred brand is Cento. My ingredients are stored in a hierarchical category tree, so the preferred ingredient is a child of the ingredient in that tree.

Here's my simplified database setup:

recipes
- name
- instructions

ingredients
- name

recipe_ingredients
- recipe_id
- ingredient_id
- preferred_ingredient_id
- amount

And the associations:

class Recipe < ActiveRecord::Base
  has_many :recipe_ingredients
  has_many :ingredients, :through => :recipe_ingredients
  has_many :preferred_ingredients, :through => :recipe_ingredients
end

class Ingredient < ActiveRecord::Base
end

class RecipeIngredient < ActiveRecord::Base
  belongs_to :recipe
  has_one :ingredient
  has_one :preferred_ingredient
end

I'm not sure how to handle that preferred_ingredient_id and ingredient_id both point to the same model and that :preferred_ingredients doesn't actually exist as a symbol. Do I need to set up my associations differently?

Upvotes: 0

Views: 56

Answers (2)

swapab
swapab

Reputation: 2410

You may also have a look @ self-referential-association

and also this might help you Rails Associations - has_many => :through - but same model

Upvotes: 0

user684934
user684934

Reputation:

Assuming you're storing the ingredient reference in RecipeIngredient,

belongs_to :preferred_ingredient, class_name: 'Ingredient'

I'd also think you're referencing the ingredients in RecipeIngredient, so you'd want to change the has_one to belongs_to there as well. (Would it make sense that the ingredient is destroyed if the recipe is deleted?)

But considering that you may actually have many options for a particular ingredient, you might be looking for something more like this:

RecipeIngredient:

belongs_to :recipe
belongs_to :preferred_ingredient, class_name: 'Ingredient'
has_many :ingredient_options
has_many :ingredients, through: :ingredient_options

IngredientOption

belongs_to :recipe_ingredient
belongs_to :ingredient

Upvotes: 1

Related Questions