2

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();
    });
HashtagForgotName
  • 651
  • 1
  • 7
  • 23
  • Did you add your relations in your model using `morphMany`? This is well documented by the way. Why do you convert to an array? Wouldn't it be better to return models? – Gert B. Aug 31 '21 at 13:08
  • i convert it into an array to access it better in javascript, I did set up the relations likes the docs pointed out and it gets the right relations ship but on that `item_type`, `item_id` i want to query the items that belongs to that items and I can not figure out how to make if the `type is post` it takes `return $this->morphedByMany(Post::class, 'bookmark_item');` and for `comment` `return $this->morphedByMany(Comment::class, 'bookmark_item');` but I can not see how to that in the query – HashtagForgotName Aug 31 '21 at 13:32
  • https://laravel.com/docs/8.x/eloquent-relationships#one-to-one-polymorphic-retrieving-the-relationship Like this but then i need to still loop to each item and do `->bookmark_item` to get the post or item unless u can do that in the query what I don't know how – HashtagForgotName Aug 31 '21 at 13:33
  • I feel like, after two days of staring at this problem, I'm starting to understand what I'm thinking wrongly about, but I need some information. Can you post a database schema, and something akin to UML for the models in play? I feel like you are using a morph to many without the center table that drives the morphing, but I can't be sure. – Clayton Engle Sep 02 '21 at 14:57
  • I have a center table ill post screenshots but the morph works in PHP i can do `$bookmarkitem->bookmark_item` and it returns the correct item But its just that how u do that in the query but ill add all the scemes in edit – HashtagForgotName Sep 02 '21 at 20:08
  • I see that with both `with` append value, you get the related posts and comments queried and attached to your bookmark item. I don't understand what you need more: you would like to have both posts and comments under the same attribute array on the bookmark item ? – Mtxz Sep 03 '21 at 13:09
  • if i add with into the model or the query like pointed out in the screenshot it gets a comment on a post model type what should not be happening cause it also gets the related comment to that while the type is `model/app/post` so on each item it querys it should check the type first before getting related model what it currently is not doing if u add with into the query or model – HashtagForgotName Sep 03 '21 at 14:59
  • what happends if you use this?$posts = $bookmark->posts()->get() ->toArray(); $comments = $bookmark->comments()->get() ->toArray(); and set your relations in bookmark model instead of bokmark_items model – soroush ganjooe Sep 05 '21 at 09:23
  • i mean do your structure like this : https://laravel.com/docs/8.x/eloquent-relationships#many-to-many-polymorphic-relations – soroush ganjooe Sep 05 '21 at 09:26
  • @soroushganjooe that works fines i can even do $post = $bookmark_items->with('post')->where('type', 'model/app/post')->get(); Only then i get 2 seperate arrays of items and i would love to have 1 so i can for example sort them by date and let sql do that instead of have to filter after that in a foreach loop, Also yes i have that structure – HashtagForgotName Sep 05 '21 at 10:57

0 Answers0