简体   繁体   English

创建餐厅菜单我应该使用has_many通过或habtm关联吗?

[英]Creating a Restaurant Menu should I use a has_many through or habtm association?

I am attempting to create a Restaurant project and design the database for the menu. 我正在尝试创建一个Restaurant项目并设计菜单的数据库。 While creating the database schema, I seem to keep spinning my wheels on how to implement the correct associations among the following models MenuItem, Menu, and a Menu Section . 在创建数据库模式时,我似乎一直在努力探索如何在以下模型MenuItem, Menu, and a Menu Section之间实现正确的关联。 Every time I go through the has_many :through , and has_and_belongs_to_many , I can see the benefits of both but then when I implement them I get confused. 每次我通过has_many :throughhas_and_belongs_to_many ,我都能看到两者的好处,但是当我实现它们时,我会感到困惑。 Additionally, I have the confusion of a self join to the mix which further throws me off. 另外,我对混合的self join感到困惑,这进一步使我失望。

I think that I am over engineering but some input into the database schema would be helpful. 我认为我的工作量过大,但是对数据库架构的一些输入会有所帮助。 More specifically, which association should I use for the following scenario in your opinion? 更具体地说,您认为以下情况我应使用哪种关联?

So far I have three classes/tables Restaurant, Menu, and MenuItem and the scenario I have crafted: 到目前为止,我有三个类/表Restaurant, Menu, and MenuItem以及我Restaurant, Menu, and MenuItem的方案:

class Restaurant
  has_many :menus  (#Desert, Drinks, Dinner, Lunch, etc.)
end

class Menu
  has_many :sections, class_name: "Menu", foreign_key: "sections_id"
  belongs_to :section, class_name: "Menu"

  has_many :menu_items, through: :sections

  belongs_to :restaurant
end

## Context for the Menu and Sections
If I had a drinks menu with the following sections, Non Alcoholic, 
Spirits, Wine, etc. These 'sections' are essentially menus with 
their own menu items. This is why I put a self join on the Menu 
class. Maybe Im mistaken.


 class MenuItem
   belongs_to :section, class_name: "Menu"
   belongs_to :menu
 end 

 ####
 The menu item for example of 'Yellow Tail Merlot' belongs to the 
 section "Wine" under the menu of "Drinks". This is precisely where
 I am getting thrown off. I get the feeling that I'm making this 
 too complicated but when I say it out loud to myself it makes 
 perfect sense. 

Ok so now here is version 2 with the habtm: 好吧,现在这里是带有habtm的版本2:

class Restaurant
  has_many :menus  (#Desert, Drinks, Dinner, Lunch, etc.)
end

class Menu
   has_and_belongs_to_many :menu_items
end


 class MenuItem
  has_and_belongs_to_many :menus
  has_and_belongs_to_many :sections, class_name: "Menu"
 end 

As you can see the above code in version 2 gets hairy. 如您所见,版本2中的上述代码比较繁琐。 In fact, I don't even know if the sections part of has_and_belongs_to_many is possible. 实际上,我什至不知道has_and_belongs_to_many的section部分是否可能。 Anyways, this is my rationale taken from the Rails Associations docs. 无论如何,这是我从Rails协会文档中获取的基本原理。

A has_and_belongs_to_many association creates a direct many-to-many connection with another model, with no intervening model. has_and_belongs_to_many关联可与另一个模型直接建立多对多连接,而无需中间模型。 For example, if your application includes menus and menu items, with each menu having many menu items and each menu item appearing in many menus, you could declare the models this way. 例如,如果您的应用程序包含菜单和菜单项,并且每个菜单都有许多菜单项,并且每个菜单项都出现在许多菜单中,则可以用这种方式声明模型。

The quote is from the rails docs but I switched assemblies and parts with menus and menu items. 引文来自rails docs,但我使用菜单和菜单项切换了装配件和零件。 Reading it that way makes complete sense. 以这种方式阅读完全有道理。 So now I ask, what do you guys think? 所以现在我问,你们怎么看? Which would be better to use? 使用哪种更好? Thank you. 谢谢。

I'd use belongs_to and instead of using a self join on the Menu table, create a new class/table called Section . 我将使用belongs_to ,而不是在Menu表上使用自连接,而是创建一个名为Section的新类/表。

Updated would be: 更新为:

class Restaurant
  has_many :menus
end

class Menu
  has_many :menu_items
  has_many :sections

  belongs_to :restaurant
end

class Section 
  belongs_to :menu
  has_many :menu_items
end


class MenuItem
  belongs_to :menu
  belongs_to :section
end 

The sections you describe are more categories, eg Wine is an alcoholic drink, Wine is the menu item and 'alcoholic drink' is the category. 您描述的部分属于更多类别,例如,“酒”是一种酒精饮料,“葡萄酒”是菜单项,“酒精饮料”是类别。 You could even go one step further and have Wine associated with two sections, 'alcoholic' and 'drink'. 您甚至可以更进一步,将Wine与“酒精”和“饮料”两个部分相关联。

should I use a has_many through or habtm association? 我应该使用has_many通过或habtm关联吗?

They both can be used to create similar many to many associations. 它们都可以用于创建相似的多对多关联。 The key difference is that has_and_belongs_to_many does not use a model for the join entities. 关键区别在于has_and_belongs_to_many实体使用模型。 While this sounds simple and appealing it does have some huge cons: 虽然这听起来很简单而且很吸引人,但确实有一些弊端:

  • There is no practical way to add access additional columns on the join table. 没有实际的方法来添加访问联接表上的其他列。 For example you want to add an "position" column to sort the items - you´re out of luck with has_and_belongs_to_many . 例如,您想添加一个“位置”列来对项目进行排序-使用has_and_belongs_to_many
  • There is no way to directly query the join table. 无法直接查询联接表。

So has_and_belongs_to_many is great for those zero complexity cases and not very good in real life. 因此has_and_belongs_to_many非常适合那些零复杂度的情况,在现实生活中不是很好。 For everything else there is has_many through: . 对于其他所有内容,都有has_many through:

class Restaurant
  has_many :menus
  has_many :menu_sections, through: :menus
  has_many :menu_items, through: :menu_sections
end

class Menu
  belongs_to :restaurant
  has_many :menu_sections
  has_many :menu_items, through: :menu_sections
end

class MenuSection
  belongs_to :menu
  has_one :restaurant, through: :menu
  has_many :menu_items
end

class MenuItem
  belongs_to :menu_section
  has_one :menu, through: :menu_section
  has_one :restaurant, through: :menu
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM