Unlocking the Power of Polymorphic Relationships
What Are Polymorphic Relationships?
In software development, it’s not uncommon to encounter models that can belong to more than one entity. This type of model maintains the same structure, regardless of the other model it’s connected to. A classic example of this scenario is comments. In a blog, comments can be attached to a post or a page, while maintaining the same structure. This behavior is described as polymorphism.
A Cleaner Approach to Database Design
Traditionally, we would set up our database by creating multiple comment tables, each pointing to a different entity. However, with polymorphic relationships, we can take a cleaner and simpler approach. By merging the comment tables into one, we can use two new columns: commentable_id
and commentable_type
. The commentable_id
column contains the ID of the post or page, while the commentable_type
column contains the class name of the model that owns the record.
CREATE TABLE comments (
id INT PRIMARY KEY,
content TEXT,
commentable_id INT,
commentable_type VARCHAR(255)
);
Defining Polymorphic Relationships
To define a polymorphic relationship, we use the morphs
method in our migration, which automatically creates the commentable_id
and commentable_type
columns. We then create models for our entities, using the <code)morphmany< code=””> and morphTo
methods to define a one-to-many polymorphic relationship.</code)morphmany<>
// In the migration
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->increments('id');
$table->text('content');
$table->morphs('commentable');
});
}
// In the Post model
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
// In the Comment model
public function commentable()
{
return $this->morphTo();
}
Accessing Data with Ease
With our polymorphic relationships set up, we can easily access data and work with this relationship through our models. We can retrieve comments for a page or post using the comments
dynamic property declared in the model. We can also reverse this retrieval, finding out which entity a comment belongs to using the commentable
method on the Comment model.
$post = Post::find(1);
$comments = $post->comments;
$comment = Comment::find(1);
$entity = $comment->commentable;
Types of Polymorphic Relationships
Polymorphic relationships come in different flavors, including:
- One-to-One Polymorphic Relationship: A situation where one model can belong to more than one type of model, but on only one association.
- One-of-Many Polymorphic Relationship: A situation where one model can have multiple associations with more than one model, but you only want to retrieve one at a time.
- Many-to-Many Polymorphic Relationship: A situation where multiple models can have multiple associations with each other.
Additional Use Cases
Polymorphic relationships have numerous use cases beyond comments. They can be used for:
- Multiple user types
- Attachments and media
- And more…
By identifying similarities between what two or more models might need, we can build on top of it instead of duplicating code and creating numerous tables.