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 votesComments