A couple of months back we had Nigel talking at WellRailed about a Foreign Key Constraint plugin he uses with Rails and then just this week the topic was brought up again for me with a client. I’ve found it’s something that pops up every now and again. Given this is such a polarizing issue I thought I’d order my thoughts into a post explaining why I don’t use foreign key constraints, in particular cascading deletes.
For me the reasoning is distilled down to my programming style.
Pragmatism
When it comes down to it, what vital benefit does it give you over :dependent => :destroy or model validation? Will this give you increased quality faster, quicker and cheaper?
Premature Optmisation
Basically don’t waste time optimising something that isn’t slow or is hardly used. Rails is so slow that some fractional speedup on the DB isn’t really going to be noticeable by the end user. Instead examine your site with NewRelic or FiveRuns and fix your bottleneck code - way more bang for your buck.
Data is Valuable
So don’t go around deleting it! If a user wants to delete some data you should want to know why. Looking at the data can aid in determining why without having to bug the user about it. Yes there are occasions when this does need to happen, but they should be the exception to the rule and thus explicitly coded for.
Just mark a record as deleted and filter it out automatically, that’s easy enough to do with rails - way easier than any other language I’ve used before. Better yet, search github and use someone else’s wheel.
Convention Over Configuration
Basically put, you do things the way that everyone else has done it. Walk the well walked path so to speak’ and you won’t experience any bizzaro problems that someone else hasn’t already solved before you. As you’ve created your app in a predictable way, someone else can easily come in and contribute to your project, or visa-versa and it makes the whole Rails community more accessible to you.
So in following the conventions and as you are not encouraged to use foreign key constraints, Rails isn’t expecting data to be deleted out from underneath it.
Don’t Repeat Yourself && Model View Controller
DRY is another of the core philosophies behind Rails - partials are a real good example of this especially when you start to think of them as essentially methods. On top of the obvious ’speed to deliver’ benefits this concept provides, it also causes you to distill your code down to being more readable and accessible. This ties in nicely with MVC principles as you then tend to group like logic together which is what MVC is all about.
Foreign key constraints are business logic as they describe and implement a behavior - “when you delete this record, also delete these other records over here”. So why would you go and put some ‘important to know about’ business logic in an isolated and often hard to reach place?
Documentation
The one great thing I learned from Steve McConnell’s Code Complete was how to write comments, they should describe the intention of the code, rather then repeat the code. This nicely ties in with the DRY principle.
I’m also a great believer in self documenting code, Rails and Ruby help heaps with this, and generally write comments to help simplify complex code. Instead of my code being littered with redundant comments cluttering everything up, it just contains important ones as they are more likely to be read and updated when the code is next worked on.
If you use foreign key constraints in your DB you’ll likely end up documenting them (ie repeating them) somewhere more accessible, in the models being an obvious place. That wouldn’t be because the business logic lives there would it?. Have a think about that.
The Rails Way
Looking at the Convention over configuration, Don’t Repeat Yourself and Model View Controller concepts above - as much as Rails is a framework it’s also about a way of doing things.
Over the years I’ve seen a notable number of people, new to rails and these concepts, trying to make rails work their way - often with less than desirable results. If you embrace Rails and it’s ‘way’ then it works beautifully and is a pure joy to use, rather than a frustrating experience.
For me
Coding is an art form and as such a creative process. If something doesn’t look, or even feel right then it’s wrong. In the end foreign key constraints on a web app just rub me up the wrong way.
Related posts:
- Starting simple with Rails caching So, you’ve launched your website and increasingly people are actually...
![[del.icio.us]](http://www.motionstandingstill.com/wp-content/plugins/bookmarkify/delicious.png)
![[Digg]](http://www.motionstandingstill.com/wp-content/plugins/bookmarkify/digg.png)
![[dzone]](http://www.motionstandingstill.com/wp-content/plugins/bookmarkify/dzone.png)
![[Fark]](http://www.motionstandingstill.com/wp-content/plugins/bookmarkify/fark.png)
![[Google]](http://www.motionstandingstill.com/wp-content/plugins/bookmarkify/google.png)
![[LinkedIn]](http://www.motionstandingstill.com/wp-content/plugins/bookmarkify/linkedin.png)
![[Reddit]](http://www.motionstandingstill.com/wp-content/plugins/bookmarkify/reddit.png)
![[Shoutwire]](http://www.motionstandingstill.com/wp-content/plugins/bookmarkify/shoutwire.png)
![[Slashdot]](http://www.motionstandingstill.com/wp-content/plugins/bookmarkify/slashdot.png)
![[Sphinn]](http://www.motionstandingstill.com/wp-content/plugins/bookmarkify/sphinn.png)
![[StumbleUpon]](http://www.motionstandingstill.com/wp-content/plugins/bookmarkify/stumbleupon.png)
![[Technorati]](http://www.motionstandingstill.com/wp-content/plugins/bookmarkify/technorati.png)
![[Twitter]](http://www.motionstandingstill.com/wp-content/plugins/bookmarkify/twitter.png)



2 Comments
Hey Nahum, great post and thanks for mentioning FiveRuns as an option for fixing code bottlenecks. It’s much appreciated.
Hey Nahum ! Great post.
Think it’s a matter of Application Database vs Integration Database when it comes down to it. If you’re building an application on top of an Integration Database, foreign key constraints will be very important. Most of us however build applications on top of Application Databases, so the key constraint layer isn’t necessarily as crucial.
http://martinfowler.com/bliki/ApplicationDatabase.html
http://martinfowler.com/bliki/IntegrationDatabase.html
Cheers !
==
Dylan