Reputation: 111
I have the following 3 tables:
Posts:
class Post extends Eloquent
{
public function comments()
{
return $this->hasMany(Comment::class,'post_id','id');
}
}
** Post data **
{
'id' : 1,
'title' : 'bla bla',
'created_at: 'some date'
}
Comments:
class Comment extends Eloquent
{
public function comments()
{
return $this->belongsTo(Post::class,'id');
}
public function tags()
{
return $this->hasMany(Tag::class,'id','tags_ids');
}
}
** Comments data **
{
'id' : 322,
'active' : true
'post_id' : 1,
'created_at: 'some date',
'tags_ids' : [1,2,3]
}
Tags:
class Tag extends Eloquent
{
public function tags()
{
return $this->belongsTo(Comment::class,'tags_ids');
}
}
** Tags data **
{
{'id' : 1,
'description' : 'some description1'
},
{'id' : 2,
'description' : 'some description2'
},
{'id' : 3,
'description' : 'some description3'
}
}
Post table has many comments and comments table has many tags associated with it.
How do i get all this tables together using eager loading?
Something like :
$post = Post::where('id',1)->with(['comments' => function($q) {
$q->with('tags');
}])->first();
but this query always returning empty response in the tags relationship.
What am i doing wrong?
The desired result is something like this:
{
'id' : 1,
'title' : 'bla bla',
'created_at: 'some date',
'comments':[{
'id' : 322,
'active' : true
'post_id' : 1,
'created_at: 'some date',
'tags_ids' : [1,2,3],
'tags' : [
{'id' : 1,'description' : 'some description1'},
{'id' : 2, 'description' : 'some description2'},
{'id' : 3,'description' : 'some description3'}
],
}
]
}
You can see that post contains comments inside it and comments contains tags relationship inside it as well.
P.S. I am using the 'jenssegers/laravel-mongodb' package in my project and i am trying to do it without any raw expression.
Thanks.
Upvotes: 0
Views: 2752
Reputation: 9029
You have defined your relationships wrong. You have tags_ids
as array in your comment model but instead you need many-to-many relationships for your tags. To implement this you have to define a new table comment-tag
:
comment-tag
comment_id - unsined big integer
tag_id - unsigned big integer
Then in you Comment
model modify tags
relationship like this:
class Comment extends Model
{
/**
* The tags that belong to the comment.
*/
public function tags()
{
return $this->belongsToMany('App\Tag');
}
}
The inverse of this relationship is:
class Tag extends Model
{
/**
* The comments that belong to the tag.
*/
public function comments()
{
return $this->belongsToMany('App\Comment');
}
}
Then to eager load nested relationships, you may use "dot" syntax:
$post = Post::with(['comments', 'comments.tags'])->find(1);
See Many-to-Many relationship on Laravel docs for more info.
Upvotes: 2
Reputation: 4813
UPDATE: You must fix your db schema
The table structure goes like this:
- posts
- id
- title
- ...
- comments
- id
- active
- post_id
- created_at
- tags
- id
- description
- comment_id
- created_at
// App\Post
class Post extends Eloquent
{
public function comments()
{
return $this->hasMany(Comment::class,'post_id','id');
}
}
// App\Comment
class Comment extends Eloquent
{
public function post()
{
return $this->belongsTo(Post::class);
}
public function tags()
{
return $this->hasMany(Tag::class);
}
}
//App\Tag
class Tag extends Eloquent
{
public function comment()
{
return $this->belongsTo(Comment::class);
}
}
//...
$post = Post::with(['comments', 'comments.tags'])->find(1);
//...
Upvotes: 0
Reputation: 12391
you can use
$post = Post::where('id',1)->with(['comments.tags'])->first();
it will load all the comments as well as comments.tags
ref link https://laravel.com/docs/6.x/eloquent-relationships
in link search Nested Eager Loading
Upvotes: 1