这很可能是一个菜鸟问题,因为人们使用这个宝石并且很多人喜欢它,但我没有达到目的。我正在查看一个项目,并且在t.references :foreign_key_table_name , :foreign_key => true
,add_foreign_key :table :foreign_key_table_name, :options
和创建t.foreign_key :foreign_key_table_name
等地方多次使用它。希望那些不会混淆,因为它们已经脱离了背景。
但我不知道这与使用t.references :foreign_key_table_name
内置的rails或仅仅添加t.integer :foreign_key_table_name_id
的内容有什么不同?通过明确这是一个“外键”,它是否只是让它更具可读性?如果是这样的话我可以添加注释而不是gem ...我看到的唯一优势是你可以将:dependent
之类的选项移到迁移中而不是在模型中使用它,但是谁在乎呢?
答案 0 :(得分:10)
某些数据库引擎支持合法的外键约束:如果有人试图保存Child
为parent_id
为5,但没有Parent
且id
为5,那么如果存在链接children.parent_id
和parents.id
的外键约束,数据库本身(不是Rails)将拒绝记录。
外键还可以指定删除父项时会发生什么:例如,在MySQL中,我们可以删除或取消依赖记录,例如Rails如何处理:dependent
,或者甚至只是直接拒绝删除并抛出错误。
由于并非所有数据库引擎都提供此功能,因此Rails提供了使用:dependent
来模拟它的功能,并且很高兴将它放在软件级别上,以便依赖子记录可以在其中发出destroy
回调。父母被删除。由于该功能与引擎无关,因此几乎与模式无关,因此Rails不处理外键的创建/删除。这就是foreigner
的用武之地:如果您的引擎支持外键约束,并且您希望对数据完整性有额外的信心,那么foreigner
可以为此提供帮助。
答案 1 :(得分:6)
在这里复活一个老问题,但是......
让rails强制执行这种关系很好,在rails本身内。
但是,如果您的项目增长以使代码也可以从其他语言访问这些表,那么这将不会有rails强制执行关系的好处。这些外键约束被绑定到SQL表本身,因此可以保护非rails代码。
如果您需要执行数据修正或以其他方式通过本机SQL操作数据,这也可以保护您。
答案 2 :(得分:0)
另一个原因是SQL的一些文档工具会查看数据库上的外键,因此拥有生成它们的gem很酷。 Rails 4添加了在创建表的同一迁移中定义外键的功能:
t.references :something, foreign_key: true
如果您使用references
类型,生成器将为您执行此操作。在使用something_id
这样的<{p>}时,Rails默认会在foreign_key
上添加索引