关于Rails的困境has_many,:通过不同类型的关系

时间:2011-04-29 23:04:14

标签: ruby-on-rails has-many has-many-through

我使用has_many进入了两难境地:通过。

假设我正在尝试通过Rails为餐馆的菜单建模。并且假设这家餐厅可以有几种不同的菜单,具体取决于用餐种类。

例如,我们将提供膳食型早餐菜单,午餐菜单等等。我们还想添加添加儿童菜单和成人菜单等功能。

显然,我们应该有一个Menu和一个Food类,我们还需要一个连接表来指定它们之间的不同菜单和HABTM关系。

但我们如何处理膳食类型?
请注意,膳食类型属于许多食物,但只属于一个菜单。我觉得将它添加到上一个连接表会效率低下。

在这个例子中,我想我会通过创建一个新的模型,MealType,写一个Food has_many:meal_types来解决:通过用餐。

然后更新菜单模型,因为菜单只能有一种膳食类型。这意味着每个菜单的MealTypes都有一个has_one关系。简言之:

食品类:

has_many Menus, :through menu_food_join_table  
has_many MealTypes, :through meals  

菜单类:

has_many Foods, :through menu_food_join_table  
has_one MealType  

MealType类:

belongs_to Foods, :through meals  
belongs_to Menus  

在这里,我陷入了困境:这段代码很臭,至少对我而言。对于简单的关系,有几个表是不切实际的。而且我认为我不应该在Foods中加入MealType字段,因为有些食物可能是几餐(比如可口可乐)。

我也不应该在菜单中添加MealType,因为我希望能够按膳食类型分开食物(例如,如果我只想显示某些食物允许的食物)。

在这种情况下你会做什么?我必须承认我对OO设计没有太多经验,这就是我来到这里的原因。


我的最终解决方案

以下是我选择解决问题的解决方案:

由于我的真正目标是以算法方式生成菜单,因为在这项工作中我不必保存任何生成的菜单,因此我销毁了Menu模型并创建了一个Meal模型。

然后我通过连接表为Food模型添加了很多Meals关系。膳食数据库中唯一的东西是我想要创造的膳食类型(早餐,午餐,晚餐等)。通过同一个联合餐桌,一顿饭有许多食物。

我仍然有菜单控制器和视图,我用它来创建一个MenuFactory。

这个MenuFactory是一个标准的工厂模式,它接收我想要生成菜单的天数和餐馆的特定算法(例如,餐厅仅供应少于300卡路里的板)并吐出整个菜单。其余的是简单的编程。

1 个答案:

答案 0 :(得分:0)

你似乎过于复杂。你有一个餐厅,它有一个早餐菜单,一个午餐菜单,一个晚餐菜单。这只是三个菜单 - 我认为你根本不需要对类型进行建模。

所以你真的需要

菜单: has_many menu_items

菜单项: belongs_to菜单

我想你可以说一个菜单项可能在多个菜单上,就像在午餐菜单上吃早餐一样 - 但是如果你不需要来搞定那么复杂的话“T

如果您要对菜单进行的操作比这更复杂,那么我建议您的主要问题是您还没有真正定义问题是什么,并且您已经尝试构建一个数据库代表你没有明确定义的东西。