I am wondering what the best way to go about this situation is from a design perspective: A has many Cs. A has many Bs. B has many Cs. Example (not the example from my real app, so hopefully it makes sense). We have restaurants. Each restaurant has many menus. Each restaurant has many dishes. Every dish /must/ belong to a menu, and every dish /must/ belong to a restaurant (conceptually). The same dish cannot belong to 2 different menus or restaurants (a dish with all the same attributes could, but in the DB its a different dish). As it is often useful to find all given dishes for a given restaurant that match some criteria, it is tempting to do this: class Restaurant has_many :dishes has_many :menus end class Menu has_many :dishes end class Dish belongs_to :restaurant belongs_to :menu end But this seems somehow bad. I know that it makes deletions work strangely (the item can be deleted from the restaurant and still found on one of its menus, etc. So right now I am doing it like this: Class Restaurant has_many :menus def dishes my_dishes = [] menus.each do |menu| menu.dishes.each do |dish| my_dishes.push dish end end end my_dishes end Class Menu has_many :dishes end Class Dish belongs_to :menu end Which works well enough, but given_restaurant.dishes now returns an array, so I cannot call ActiveRecord methods on it, (some_restaurant.dishes.find(:all, :conditions {:course => "entree"}) ) which is sometimes inconvenient. It seems like a fairly common scenario to have A has many Bs and B has many Cs, and to want to be able to efficiently access the Cs from A, so I was wondering if there was a railsier, DRYer way to go about this. Any hints/ideas/tutorial links? -- Posted via http://www.ruby-forum.com/.
Nick Green wrote:> We have restaurants. Each restaurant has many menus. Each restaurant > has many dishes. Every dish /must/ belong to a menu, and every dish > /must/ belong to a restaurant (conceptually). The same dish cannot > belong to 2 different menus or restaurants (a dish with all the same > attributes could, but in the DB its a different dish).I could be misreading your design specifications here, but it seems to me that restaurants would have many dishes through menus: class Restaurant has_many :menus, :dependent => :destroy has_many :dishes, :through => :menus end class Menu belongs_to :restaurant has_many :dishes, :dependent => :destroy end class Dish belongs_to :menu end Then you could do things like: restaurant.menus restaurant.dishes menu.dishes dish.menu.restaurant -- Posted via http://www.ruby-forum.com/.
Precisely what I''m looking for. I thought I must be missing something, somehow reading books/tutorials all at once my brain just lets some information go, and I couldn''t remember the pertinent info, but I could tell my way was not "railsish". Sorry for the silly question and thanks for the answer :) Robert Walker wrote:> Nick Green wrote: >> We have restaurants. Each restaurant has many menus. Each restaurant >> has many dishes. Every dish /must/ belong to a menu, and every dish >> /must/ belong to a restaurant (conceptually). The same dish cannot >> belong to 2 different menus or restaurants (a dish with all the same >> attributes could, but in the DB its a different dish). > > I could be misreading your design specifications here, but it seems to > me that restaurants would have many dishes through menus: > > class Restaurant > has_many :menus, :dependent => :destroy > has_many :dishes, :through => :menus > end > > class Menu > belongs_to :restaurant > has_many :dishes, :dependent => :destroy > end > > class Dish > belongs_to :menu > end > > Then you could do things like: > restaurant.menus > restaurant.dishes > menu.dishes > dish.menu.restaurant-- Posted via http://www.ruby-forum.com/.
Thanks for asking the question, it helped me understand things better. On Sep 10, 1:52 am, Nick Green <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> Precisely what I''m looking for. I thought I must be missing something, > somehow reading books/tutorials all at once my brain just lets some > information go, and I couldn''t remember the pertinent info, but I could > tell my way was not "railsish". > > Sorry for the silly question and thanks for the answer :) > > > > Robert Walker wrote: > > Nick Green wrote: > >> We have restaurants. Each restaurant has many menus. Each restaurant > >> has many dishes. Every dish /must/ belong to a menu, and every dish > >> /must/ belong to a restaurant (conceptually). The same dish cannot > >> belong to 2 different menus or restaurants (a dish with all the same > >> attributes could, but in the DB its a different dish). > > > I could be misreading your design specifications here, but it seems to > > me that restaurants would have many dishes through menus: > > > class Restaurant > > has_many :menus, :dependent => :destroy > > has_many :dishes, :through => :menus > > end > > > class Menu > > belongs_to :restaurant > > has_many :dishes, :dependent => :destroy > > end > > > class Dish > > belongs_to :menu > > end > > > Then you could do things like: > > restaurant.menus > > restaurant.dishes > > menu.dishes > > dish.menu.restaurant > > -- > Posted viahttp://www.ruby-forum.com/.