While I understand the power of Polymorphism, I also understand the basic design principles for Database Design. Polymorphism violates something I consider to be crucial to Database Design: Foreign Key Relationships.
When using Polymorphism, the two columns
<morphable>_id are used. The
<morphable>_type column references the name of a Table in the Database, and the
<morphable>_id references an ID within that Table. Nothing new here.
However, I see it as bad practice to mix Meta-Data and Data, i.e.
<morphable>_type. If a table is dropped or renamed, the Database can't naturally enforce anything. I understand that Migrations can resolve this, but it doesn't fix the fact that the Database itself can't enforce this relationship.
Furthermore, Foreign Key relationships can only reference one Parent Table. Polymorphism violates this with the
<morphable>_id column. Sure, there's no Foreign Key assigned to this column, but now you essentially have a number that has no meaning to the Database. If that key is updated, or the entry is removed, how will the Database know to remove that row? I understand that this too can be resolved, by using the Boot Method in each respective Model, but it doesn't fix the fact that the Database itself can't enforce a Foreign Key that isn't defined.
Honestly, this leaves me stuck. I know that there are other alternatives to Polymorphism that are RDBMS friendly, but all require general maintenance, or make the MVC flow feel unnatural. I'm a Database guy, so violating basic principals is hard for me to do. However, I'm also a Design guy, so I don't want to build a system that's hard to code or unnatural. Polymorphism is where these two clash, as it's an elegant solution, but it violates Database Design.
I know the pros for sticking with proper Database Design, but is Polymorphism really worth breaking principles?
Furthermore, is there a nice, general way to automatically handle all of the nasty maintenance issues that come with Polymorphism? Since Laravel is Database Agnostic, I'm willing to bend the rules a bit, as I can say that the Database Layer of my Application (which would extend into Models and Migrations) is able to successfully enforce Polymorphic relationships.