Spatie's Role and Permission package in Laravel
Read More
A polymorphic relationship allows the child model to belong to more than one type of model using a single association.
Polymorphic relationships in Laravel are a powerful feature that allows you to associate a single model with multiple other models in a single association. This concept simplifies complex database structures and enhances flexibility in handling relationships. In this blog post, we will explore the fundamentals of polymorphic relationships in Laravel, along with a complete example to help you understand and implement them effectively.
Table of Contents:
Key Components of Polymorphic Relationships Three key components are essential for understanding and implementing polymorphic relationships:
Polymorphic relationships consist of three primary elements:
Polymorphic relationships are a type of association where a model can belong to more than one other model in a single association.
In Laravel, you can achieve this using the morphTo
and morphOne
or morphMany
methods provided by the Eloquent ORM.
To implement polymorphic relationships in Laravel, you will need to create three database tables: posts
, comments
, and images
.
Theposts
table will store all the posts in the application.
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('body');
$table->timestamps();
});
The comments
table will store all the comments made on the posts:
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->text('comment');
$table->morphs('commentable'); // Add this line
$table->timestamps();
});
The images
table will store all the images associated with either posts or comments.
Schema::create('images', function (Blueprint $table) {
$table->id();
$table->string('path');
$table->morphs('imageable'); // Add this line
$table->timestamps();
});
Themorphs
method generates the necessary *_id
and *_type
columns in the table to store the ID and type of the parent model.
Next, you need to define the relationships in the respective models:
In the Post
model:
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
public function image()
{
return $this->morphOne(Image::class, 'imageable');
}
In the Comment
model:
public function post()
{
return $this->belongsTo(Post::class);
}
public function image()
{
return $this->morphOne(Image::class, 'imageable');
}
In the Image
model:
public function imageable()
{
return $this->morphTo();
}
Now, you can retrieve all the comments associated with a post and the image associated with each comment:
$post = Post::find(1);
foreach ($post->comments as $comment) {
echo $comment->comment . '<br>';
echo $comment->image->path . '<br>';
}
Similarly, you can retrieve the post and comment associated with an image:
$image = Image::find(1);
if ($image->imageable_type === 'App\Models\Post') {
echo $image->imageable->title . '<br>';
} elseif ($image->imageable_type === 'App\Models\Comment') {
echo $image->imageable->comment . '<br>';
echo $image->imageable->post->title . '<br>';
}
Similarly, you can store the post and comment associated with an image.
$comment= Comment::create($data);
// Store attachments
if ($request->hasFile('attachments')) {
$file = $request->file('attachments') ;
$uniqueIdentifier = Str::random(10);
$filename = $uniqueIdentifier . '_' . $file->getClientOriginalName();
$attachmentUrl = Storage::disk('public')->putFileAs('attachments', $file, $filename);
$attachment = new Attachment([
'filename' => $filename, // extra fields added
'path' => $attachmentUrl, // extra fields added
]);
$comment->attachments()->save($attachment);
}
That's it! You have successfully implemented polymorphic relationships in Laravel.
In this example, a post can have an image, a comment can have an image, and a comment belongs to a post. By using polymorphic relationships, you can have a flexible and extensible database structure that can accommodate various associations in your application.
Recent posts form our Blog
0 Comments
Like 0