Multilevel relationship whereHas on eloquent Model in Laravel


Multilevel relationship whereHas on eloquent Model in Laravel



I'd like to find

Project::with('tasks.tags')->get();



Project::with('tasks.tags')->get();



where only projects with a particular id of tag return in the result set.



For ex. I'd like to find a project with tasks and tasks with tags with only id of 1. In other words, filter the tasks return inside of the Project - Task relationship.



I have tried various ways but have failed so far.



I have tried:


$project = Project::with('tasks.tags')->whereHas('tasks', function($query){
$query->whereHas('tags', function($query) {
$query->where('id', 1);
});
})->get();



And:


$project = Project::with('tasks.tags')->whereHas('tasks', function($query){
$query->whereHas('tags', function($query) {
$query->where('tag_id', 1);
});
})->get();



This is how the relationships are setup:



In Project.php


public function tasks()
{
return $this->hasMany(Task::class, 'project_id')->setEagerLoads();
}



In Task.php


public function tags()
{
return $this->morphToMany(Tag::class, 'taggable')->setEagerLoads();

}



Note that relationship between Task and Tags is of morphToMany.



Any pointers?





Is there a reason you force eager loads to be unset in your relationship definitions?
– Namoshek
Jun 30 at 6:17





Yes. The Tag class Task class are set as nested tree and I had to load their children recursively. Adding $with = ['children'] allowed me to easily load their children. If I do this manually, I have load 'children' recursively manually for each Task and Tag returned as children as well.
– stirredo
Jun 30 at 6:21





Okay, makes sense. Did you try your first example with hard coded ids or with variables?
– Namoshek
Jun 30 at 6:24





Hey, can you check the description again. Made some edit. I'd like to find all projects with a particular tag. I accidentally asked the wrong thing. I have been stuck on this problem for a few hours now and my head isn't right :D
– stirredo
Jun 30 at 6:26





It doesn't through any error at all. The query just doesn't filter the tasks at all. What I'd like to do is filter the project's Task with only Tag of a particular ID. Say 1.
– stirredo
Jun 30 at 6:39




2 Answers
2



You would need to scope the eager loading as well. Something like the following should work:


$project = Project::with(['tasks.tags' => function ($query) {
$query->where('id', 1);
}])->whereHas('tasks', function ($query) {
$query->whereHas('tags', function ($query) {
$query->where('id', 1);
});
})->get();



Found the answer over here.


Project::with(['tasks' => function($q) {
$q->whereHas('tags', function($query) {
$query->where('tag_id', 1);
});
}])->get();






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Comments

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

how to run turtle graphics in Colaboratory

Export result set on Dbeaver to CSV