Nostalgia warning: I also grew frustrated with Rails / ActiveRecord and jumped to Merb / DataMapper with excitement. Perhaps it will sound like a small thing, but I remember feeling especially frustrated that every ActiveRecord model became such via inheritance. This drove me crazy: class User < ActiveRecord::Base
Why should my `User` extend from `ActiveRecord::Base`? Is a User of my app also an ActiveRecord::Base? What is an ActiveRecord::Base anyway?So, when DataMapper came along and favored composition over inheritance I was sold. However, my experience with DataMapper was that it didn't have the stability of ActiveRecord, nor did it reach feature parity. And, then Rails killed Merb. At the time I thought it was a tragedy. The competition Merb provided did improve Rails, it would have been nice if that competition had been longer term, though. On the flipside, I wonder if there would have been enough community to support two large Ruby web frameworks. In the end I made peace with Rails and ActiveRecord (and, believe it or not, even ActiveSupport!). I don't have great love for Rails, but it is a powerful tool, so I accept it for what it is. That said, I think the author's criticisms are well stated and hopefully there will be some influence on the future direction of Rails, etc, and the way devs approach Rails. |
Databases aren't object-oriented. Thinking of them with an is-a, LSP etc. mindset is a recipe for pain down the road. Databases are containers for facts: a means of storing, finding, synthesizing and manipulating facts. Your User class isn't a user of your application; IMO it's wrong to think of it as an object, because it could just be a slice of the User's facts (e.g. a subset of the columns).
I'm not a big fan of object orientation any more, and I like my databases to be stores of facts. The data in the database is primary; code in the application is secondary. Persistence isn't something I add to my benighted objects to let them be reanimated by query; persistence is what lets me briefly get a handy representation of a tuple locally.
To my mind, ActiveRecord models are little more than hashes with a nicer syntax. I don't need them to be much more; I don't want them to be much more. You can try and add methods and make them smaller, but coordinating the manipulation of facts is problematic in a transactional world, and the responsibilities aren't clear either. Object orientation is predicated on the idea of message sends and hidden state; tables have explicit state and no behaviour. Not a good match.