这很可能是一个愚蠢的问题,因为人们使用这个宝石,很多人都喜欢它,但我不明白目的。我看到的是一个项目,它在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
内置的铁轨有什么不同,或者我只是添加了t.integer :foreign_key_table_name_id
?它是否只是通过明确这是一个"外键"来提高可读性?如果是这样的话,我可以添加一个评论而不是宝石。。。我看到的唯一优势是,您可以将:dependent
等选项移动到迁移中,而不是将其放在模型中,但谁在乎呢?
一些数据库引擎支持合法的外键约束:如果有人试图保存parent_id
为5的Child
,但没有Parent
为id
5,那么如果存在链接children.parent_id
和parents.id
的外键约束,则数据库本身(而非Rails)将拒绝该记录。
外键还可以指定如果删除父级会发生什么:例如,在MySQL中,我们可以删除或取消依赖记录,就像Rails对:dependent
的处理一样,甚至直接拒绝删除并抛出错误。
由于并不是所有的数据库引擎都提供这种功能,Rails提供了用:dependent
来模拟它,并且在软件级别上拥有它是很好的,这样依赖的子记录就可以在删除父记录时触发它们的destroy
回调。由于该特性与引擎无关,因此与模式无关,Rails不处理外键的创建/删除。这就是foreigner
的作用所在:如果您的引擎支持外键约束,并且您希望对数据完整性有额外的信心,那么foreigner
可以帮助实现这一点。
在这里重新提出一个旧问题,但是…
在rails内部,让rails来加强这种关系是很好的。
但是,如果您的项目的代码也可以从其他语言访问这些表,那么rails将无法强制实现这些关系。这些外键约束被烘焙到SQL表本身中,因此可以保护非rails代码。
如果您需要通过本机SQL执行数据固定或以其他方式操作数据,这也将保护您。
另一个原因是SQL的一些文档工具会查看数据库上的外键,所以有一个生成外键的gem是很酷的。Rails4增加了在创建表的迁移中定义外键的能力:
t.references :something, foreign_key: true
如果您使用references
类型,生成器将为您执行此操作。Rails在使用类似的foreign_key
时,默认情况下会在something_id
上添加索引