John Davidson

php - query polymorphic relationships with related models in laravel 8

0 comments
Message:


So I want the corresponding items that belong to the correct relationship so when the type is App\\Models\\Post it should get a post item with it and if the type is App\\Models\\Comment it should get a comment with it etc


The query


$result = $bookmark->items()
->where(function ($query) {
$query
->where(function ($query) {
$query->where('bookmark_item_type', 'App\\Models\\Post')->With('posts');
})
->orWhere(function ($query) {
$query->where('bookmark_item_type', 'App\\Models\\Comment')->With('comments');
});
})
->get()
->toArray();

The result


     0: {id: 1, bookmark_item_id: 2, bookmark_item_type: "App\Models\Post", bookmarks_id: 1, created_at: null,…}
bookmark_item_id: 2
bookmark_item_type: "App\\Models\\Post"
bookmarks_id: 1
created_at: null
id: 1
updated_at: null

1: {id: 28, bookmark_item_id: 12, bookmark_item_type: "App\Models\Comment", bookmarks_id: 1,…}
bookmark_item_id: 12
bookmark_item_type: "App\\Models\\Comment"
bookmarks_id: 1
created_at: null
id: 28
updated_at

The comment or post doesn't even show up in the result.


EDIT:


I ended up with this but it would still be nice if this can be done in 1 query! so I can add date filters or DESC or ASC filters.


    $posts = $bookmark->items()
->where("bookmark_item_type", 'App\\Models\\Post')
->with('posts')
->get()
->toArray();

$comments = $bookmark->items()
->where("bookmark_item_type", 'App\\Models\\Comment')
->with('comments')
->get()
->toArray();

More EDITS!


I have looked at this post Laravel - Eager Loading Polymorphic Relation's Related Models but when I add the relations like this into mine model


protected $with = [
'posts',
'comments',
];


It still loads the comment with the post type and vice versa here the models am I missing something? or can I add something into the query with an extra filter on the with? for each individual item? cause I can not get the data with $bookmarkitem->bookmark_item cause I m using ajax to get the data request so I can not do that in the front end to get my post or comment


Models:


class BookmarkItem extends Model
{

public function posts(): \Illuminate\Database\Eloquent\Relations\MorphToMany
{
return $this->morphedByMany(Post::class, 'bookmark_item');
}


public function comments(): \Illuminate\Database\Eloquent\Relations\MorphToMany
{
return $this->morphedByMany(Comment::class, 'bookmark_item');
}
}

class Post extends Model
{
public function bookmarkItem()
{
return $this->morphToMany(BookmarkItem::class, 'bookmark_item');
}
}

class Comment extends Model
{
public function bookmarkItem()
{
return $this->morphToMany(BookmarkItem::class, 'bookmark_item');
}
}

DB Schemes of database


Schema::create('bookmark_items', function (Blueprint $table) {
$table->id();
$table->integer('bookmark_item_id')->unsigned();
$table->string('bookmark_item_type');
$table->unsignedBigInteger('bookmarks_id');
$table->foreign('bookmarks_id')->references('id')->on('bookmarks');
$table->timestamps();
});

Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string("title");
$table->string("uuid")->unique();
$table->string("image_path");
$table->LongText("description")->nullable();
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
$table->timestamps();
});

Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->integer('user_id')->unsigned();
$table->integer('parent_id')->unsigned()->nullable();
$table->text('comment');
$table->integer('commentable_id')->unsigned();
$table->string('commentable_type');
$table->timestamps();
});

Schema::create('bookmarks', function (Blueprint $table) {
$table->id();
$table->string("type")->default("default");
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
$table->timestamps();
});


My Answer:
To query polymorphic relationships with related models in Laravel 8, you can use the following approach:

1. Define the relationships in your models:

php
class BookmarkItem extends Model
{
public function bookmarkable()
{
return $this->morphTo();
}
}

class Post extends Model
{
public function bookmarkItems()
{
return $this->morphMany(BookmarkItem::class, 'bookmarkable');
}
}

class Comment extends Model
{
public function bookmarkItems()
{
return $this->morphMany(BookmarkItem::class, 'bookmarkable');
}
}


2. Query the relationships with the related models:

php
$bookmarkItems = BookmarkItem::with('bookmarkable')
->where('bookmark_item_type', 'App\Models\Post')
->orWhere('bookmark_item_type', 'App\Models\Comment')
->get();

foreach ($bookmarkItems as $bookmarkItem) {
if ($bookmarkItem->bookmarkable instanceof Post) {
// Handle Post
$post = $bookmarkItem->bookmarkable;
} elseif ($bookmarkItem->bookmarkable instanceof Comment) {
// Handle Comment
$comment = $bookmarkItem->bookmarkable;
}
}


This way, you can query the polymorphic relationships and access the related models based on their type. Make sure to adjust the model and relationship names according to your actual implementation.

Rate this post

5 of 5 based on 7958 votes

Comments




© 2024 Hayatsk.info - Personal Blogs Platform. All Rights Reserved.
Create blog  |  Privacy Policy  |  Terms & Conditions  |  Contact Us