If I'm being completely honest, I'm mildly anti-ORM. I'm not about to go on a rampage and suggest they should absolutely, never, ever, ever be used, but I think they tend to create a lot of problems. Instead of being a true mapping between our object model and our relational model, they're their own tool, with its own idosynchracies, and a lot of "magic" that conceals its actual operation. For simple applications, they're great, but once you start getting into something more complicated than basic CRUD operations, you're in for a world of hurt. And that's before someone makes a mistake with eager vs. lazy fetching.

Today's anonymous submission offers us a good example of another way the mismatch can go wrong between objects and relations.

class Category_Product_Model extends Product_Model {
  protected $table_name = "categories_products";

Product_Model is the model for our products in our ecommerce solution. Category_Product_Model is the join between products and categories. In no sane world would we consider Category_Product_Model a subclass of Product_Model- this implies that we can use a Category_Product in place of a Product. How much would you charge for a link between a product and it's category? I happen to know that Legos belong in both the "toy" category and the "model building" category- what price would you put on that information? Who's the vendor? (Me, I guess?) How many of those links do I have in inventory? Why… as many as you like. It's just information.

There are a few reasons this code might be like this. The most likely, I think, is that someone just didn't care. It's all models, pick one, inherit off it, and move on to the next. But there's another reason, which would be so much worse.

You see, they could have put functionality into Product_Model. It could be more than a simple model object, and have helper functions- helper functions which Category_Product_Model also wants to use. Instead of doing the right thing and refactoring that functionality out of the models, someone decided that inheritance was a convenient way to inject useful functionality into classes.

Our anonymous submitter points out that this code had been in production for seven years by the time they found it, and this use of "creative subclassing" was rampant throughout their data model.

[Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!