Sunday, December 4, 2011

Backend Paralysis

Fellow Code Cadets, I need your help.

Today, I wanted to get the models of my breakable toy - a beer pairing application - up and running.  But then, I hit a snag: I couldn’t figure out whether to use has_many :throughs to create many-to-many associations OR if I should just use polymorphic associations.  I’m pretty sure the best solution is many-to-many, but I might also be leaning that way because I’m not sure if I really understand polymorphic associations.

In a nutshell, I would like to be able to pair beers styles with different cuisine types (e.g. Thai, Mexican, etc.) and/or main ingredient (e.g. beef, pork, chicken) and/or spices (e.g. heavy on cilantro, garlic, etc.  My boss, who has been at this for 30 years, is going to give me a better explanation of the “spice” thing).  However, once a pairing has been made, I would also like to tell the user why the pairing works.  I would also like to be able to do the opposite: isolate a cuisine, main ingredient, or spice and give users beers that pair with them.

And so, I think I’m going to need five models: Beer, Cuisine, Main_Ingredient, Spice, and Pairings. The associations will look like this:

class Pairings
belongs_to :beer
belongs_to :cuisine
belongs_to :main_ingredient
belongs_to :spice
end

class Beer
has_many :cuisines, :through => :pairings
has_many :main_ingredients, :through => :pairings
has_many :spices, :through => :pairings
end

class Cuisine
has_many :beers, :through => :pairings
end

class Main_Ingredient
has_many :beers, :through => :pairings
end

class Spice
has_many :beers, :through => :pairings
end

If I’m understanding polymorphic associations correctly - which I’ve mainly learned about by reading the RoR guide and random blog posts like this one and this one - they’re great if you want to set up relationships between models WITHOUT creating another join table. However, since I will want to include additional information as to why the pairings work - e.g. a string that is associated with a specific pairing - using has_many :through and the Pairings table seems to make the most sense.

I’m hoping that a) this post made sense and b) someone will opine.   

Until then, back to beer pairing!  I may also need some help turning CSVs into models once I get all of these beer and food relationships established…