query polymorphic relationships with related models in laravel 8

1.2k Views Asked by At

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',
];

enter image description here

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();
    });
0

There are 0 best solutions below