The Perils Of Opinionated Software (like Rails)
This is a guest opinion piece by Xavier Shay.
Ruby on Rails, by its own admission, is an opinionated framework. From day one it has positioned itself as the Kryptonite to enterprise software, providing an easy to use, rapid development framework. The infamous 15 minute blog video set a tone which has continued through to this day: if it's not quick to build and in Ruby, we're not interested.
Rails takes an extreme viewpoint, the polar opposite of the XML heavy, configuration tangled mess of traditional enterprise software. This viewpoint is necessary---without it we have no alternative---but that doesn't mean it is the best way to build applications. In their book "First, Break All The Rules", Marcus Buckingham and Curt Coffman explain that the the common method of selecting top managers by looking for the opposite of bad managers is wrong. Research showed that this strategy tended to select good managers, but not the best managers. They found that the best and worst managers actually share a lot of the same characteristics! If you want good managers, then study good managers, not bad ones. The same principle applies to software: you won't figure out how to build the best software by studying the worst.
Studying the bad is exactly the approach the Rails team has taken, though. They have studied enterprise software, and built the opposite. In the process, they have unquestionably made some breakthroughs in how to write quality software fast (that's why we all use it!), but in what ways have they thrown the baby out with the bathwater? What attributes of the worst enterprise software are also found in the best software?
Relational databases have been around for decades, and are solid pieces of infrastructure. They can do some really cool stuff, but Rails considers them no more than a necessary evil. The less the database does, the better. I appreciate the philosophy: if we can move logic from the database in to our ruby application code, that's a win, right? In practice however, this doesn't work. It physically cannot work. In addition, it's actually slower (in terms of development time) and _less_ maintainable to do certain things in ruby rather than the database!
Relational databases know how to manage relational data. That's what they do, it's in their name. Referential integrity ensures that a child row always has a valid reference to a parent row. If a child has parent_id of 1, then a parent with an id of 1 is guaranteed to exist. Referential integrity has been a solved problem for decades using foreign keys. It is a proven fundamental property of solid applications, yet Rails has no best practice for using them. Rails has tried to reinvent the wheel and do it in ruby (with the
has_many :dependent option), but it's half baked and cannot cover even simple edge cases. Try this thought experiment: one of your application servers adds a child row to a parent, while another one deletes that same parent at the same time. How you can prevent the child row from being orphaned? You can't, not without using your database.
Even something as simple as not null constraints, a fundamental principle of data design, are thrown away in the extreme polarized Rails opinion. You can just use
validates_presence_of! Once again nice in theory, but I have yet to see a large evolving Rails application that hadn't had at least one null in its database where it shouldn't have been (subsequently causing errors). Even if I had, it's the cheapest safety net you can buy: all it "costs" you is a
:null => false declaration in your migration and you never have to think about it again. No one in your team, not even the new rookie graduate, ever has to think about it again or run the risk of accidentally bypassing validations.
I'm not faulting the Rails team here. They have taken a hard line position and stuck with it, which is important for our industry. As software professionals though, we have a very different mandate than the Rails team. They are defining and pushing the boundaries of how we build software, where as our job is to find the best compromise of existing technologies to provide business value. This sweet spot will inevitably lie somewhere between extreme opinions.
This is a guest post by Xavier Shay. He is touring his "Database Is Your Friend" training course through the US and UK in July, August and September, in which he teaches you how to find the sweet spot of database usage for building rock solid Rails applications without compromising your velocity. The tour is more than likely coming to your city, so check www.dbisyourfriend.com for more details.