Are foreign keys in Rails generally avoided?

匿名 (未验证) 提交于 2019-12-03 03:03:02

问题:

Rails has no way of creating foreign keys in migrations (there are plugins to do this, however). There are also plenty of cascading options so you can get cascading deletes, for example.

With all of these options built in, is it worth creating foreign keys in the database? Is this something Rails developers normally avoid or what? You'd think if it was a recommended practice that Rails would natively support it.

回答1:

This is something of a holy issue, because DHH (the creator of Rails) has stated before that he sees the database as essentially a giant hash table, so taking advantage of some of the things that database engines are good at by using features such as constraints or stored procedures is not considered The Rails Way by Rails purists.

That said, if you'd like to enforce the integrity of your data closest to the data, or if your database is shared by other applications then by all means use one of those plugins to create the foreign keys. After all, what harm could it do, right?



回答2:

Just adding to John Topley's answer, I did a bit of research and found some of DHH's thoughts on the topic, which make for an interesting read:

I couldn't find DHH referring to the database as a "giant hash", so maybe John is paraphrasing a different quote. I'd love to read a more up-to-date version of DHH's opinion.

I didn't find too many opinions from other people written in the last couple of years. Here are the ones I found:



回答3:

Rails doesn't prevent you from using foreign key constraints in your database, it just doesn't give them to you by default. The "Rails Way" is to depend on Rails to manage your database, cascade your deletes, enforce referential integrity, etc.

There are several plugins to add foreign key constraints to your migrations, but I usually opt to add them manually. Assuming you've created CreateUsers and CreatePosts migrations, you could add a "LinkPostsToUsers" migration:

# Assumes PostgreSQL class LinkPostsToUsers < ActiveRecord::Migration   def self.up     execute "       ALTER TABLE posts          ADD CONSTRAINT fk_posts_user_id         FOREIGN KEY (user_id) REFERENCES users(id)         ON DELETE CASCADE         ON UPDATE CASCADE"   end    def self.down     execute "ALTER TABLE posts DROP CONSTRAINT fk_posts_user_id"   end end 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!