我想创建一个饮料数据库。
每种饮料都含有许多成分,成分含量很多。
因此,一种成分属于剂量,剂量属于鸡尾酒。
但是,一旦我删除饮料,我想删除相关的剂量,但不是因为可以在其他饮料中使用。
目前我正在考虑像这样构建我的数据库。
rails g model drink name:string dose_id:references
rails g model dose cl:string ingredient_id:references
rails g model ingredient name:string
问题:
1)这是否符合我的需要,还是我错过了什么?
2)我是否需要鸡尾酒和配料之间的关系,还是通过剂量来完成?如果是/否,为什么?
3)这个:引用除了将FK链接到PK之外还做什么吗?
4)命名对于引用是否重要,它如何检测要链接的表?
答案 0 :(得分:2)
我假设您使用MySQL和Ruby 2.我建议您可以像这样构建模型:
class Drink < ActiveRecord::Base
has_many :doses, dependent: :destroy
has_many :ingredients, through: :doses
end
class Dose < ActiveRecord::Base
belongs_to :drink
belongs_to :ingredient
end
class Ingredient < ActiveRecord::Base
has_many :doses, dependent: :restrict
has_many :drinks, through: :doses
end
Rails中的关系遵循一些约定:
:othertable_id
belongs_to
关系的模型还包含外键(在您的情况下,这将是:drink_id
和:ingredient_id
)。:through
语句为您在SQL中生成连接语句,因此您可以说my_drink.ingredients
或my_ingredient.drinks
。dependent: :destroy
会在删除饮品时销毁:doses
,但不会与ingredients
相关联。dependent: :restrict
将拒绝删除一种仍然被一剂或多剂量使用的成分我总是在连接表中使用额外的模型(你可以跳过它,并且rails会为你带来魔力)。但最大的好处是,您可以将额外的属性存储到该模型中,例如金额,单位......在您的红宝石代码中也很清楚,关系来自哪里。
这些模型尚未经过测试,如果:through
语法正确,我不能100%确定。但你应该明白这一点。
答案 1 :(得分:2)
您可以在rails指南上阅读有关参考和迁移的更多信息,但这里有一些想法。
你似乎错过了一些东西。您希望drink
有多个ingredients
。为drink
添加dose
的引用意味着drink
只属于一个dose
,因为它一次只能存储一个dose_id
。
您可能希望drink
和ingredients
之间存在多对多关系。 drink
可以包含多个ingredients
。一种成分可以是许多drink
的一部分。 dose
实际上可以更成功地解决此问题。
rails g model drink name:string
rails g model dose cl:string ingredient:references drink:references
rails g model ingredient name:string
它的行为应该与SQL中的典型REFERENCES
约束相同。下面是一些很好的读取,但在Rails中它还会在列上添加btree
索引。
一个。 http://www.postgresql.org/docs/9.4/static/ddl-constraints.html#DDL-CONSTRAINTS-FK
生成迁移时,它会使引用关系中的模型名称复数化。
rails g model dose ingredient:references
变得类似于架构中的以下内容:
...
add_index "doses", ["ingredient_id"], name: "index_doses_on_ingredient_id", using: :btree
add_foreign_key "doses", "ingredients"