可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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