Search code examples
laraveleloquenthas-manybelongs-torelationships

laravel eloquent get related tasks based on a auth user and project id


Hi I'm confused as how I should write my eloquent query I want to retrieve the auth user project by its id and also fetch its related tasks these have a hasMany relationship, I also want to fetch the related client, to who the project belongs to, this is in the projects and the tasks table client_id ideally I want to visit this page at something like app.dev/project/3/tasks thats simple enough to route to:

Route::any("project/{resource}/tasks", [
        "as"   => "project/projectrelatedtasks",
        "uses" => "ProjectController@projectrelatedtasks"
    ]);

I'm not sure what the easiest way to write this query would be, I can easy fetch want I need below in bulk like so in my repository:

public function getProjectTasks() {
//This fetches the auth users projects, the client to who it belongs and its related tasks
//not sure how to insert another find with $id 
    return \User::with(array('projects', 'projects.clients', 
    'projects.tasks'))->find(Auth::user()->id);
}

and this in my controller:

public function projectrelatedtasks() {
            $projects = $this->project->getProjectTasks();
            return $projects;
        }

but I want to limit it to a project by its id, not sure what the best and most efficient way to perform this query, can somebody help me figure this out please? thanks

Edit

Repository:

public function getProjectTasks($id) {

    return \Projects::with(['clients', 'tasks'])
        ->whereUserId(Auth::user()->id)
        ->find($project_id);
}

routes:

Route::any("project/{resource}/tasks", [
        "as"   => "project/projectrelatedtasks",
        "uses" => "ProjectController@projectrelatedtasks"
    ]);

controller:

public function projectrelatedtasks($id)
    {

    // get the Project tasks
        $project = $this->project->getProjectTasks($id);
        return $project;        
    }

error log:

[2014-09-10 20:56:50] production.ERROR: exception 'Symfony\Component\HttpKernel\Exception\NotFoundHttpException' in /media/sf_Sites/tempus/bootstrap/compiled.php:5687
Stack trace:
#0 /media/sf_Sites/tempus/bootstrap/compiled.php(5004): Illuminate\Routing\RouteCollection->match(Object(Illuminate\Http\Request))
#1 /media/sf_Sites/tempus/bootstrap/compiled.php(4992): Illuminate\Routing\Router->findRoute(Object(Illuminate\Http\Request))
#2 /media/sf_Sites/tempus/bootstrap/compiled.php(4984): Illuminate\Routing\Router->dispatchToRoute(Object(Illuminate\Http\Request))
#3 /media/sf_Sites/tempus/bootstrap/compiled.php(717): Illuminate\Routing\Router->dispatch(Object(Illuminate\Http\Request))
#4 /media/sf_Sites/tempus/bootstrap/compiled.php(698): Illuminate\Foundation\Application->dispatch(Object(Illuminate\Http\Request))
#5 /media/sf_Sites/tempus/bootstrap/compiled.php(7706): Illuminate\Foundation\Application->handle(Object(Illuminate\Http\Request), 1, true)
#6 /media/sf_Sites/tempus/bootstrap/compiled.php(8309): Illuminate\Session\Middleware->handle(Object(Illuminate\Http\Request), 1, true)
#7 /media/sf_Sites/tempus/bootstrap/compiled.php(8256): Illuminate\Cookie\Queue->handle(Object(Illuminate\Http\Request), 1, true)
#8 /media/sf_Sites/tempus/bootstrap/compiled.php(10895): Illuminate\Cookie\Guard->handle(Object(Illuminate\Http\Request), 1, true)
#9 /media/sf_Sites/tempus/bootstrap/compiled.php(659): Stack\StackedHttpKernel->handle(Object(Illuminate\Http\Request))
#10 /media/sf_Sites/tempus/public/index.php(49): Illuminate\Foundation\Application->run()
#11 {main} [] []

Error log 2

[2014-09-10 21:01:58] production.ERROR: exception 'ErrorException' with message 'Undefined variable: project_id' in /media/sf_Sites/tempus/app/Acme/Repositories/DbProjectRepository.php:64
Stack trace:
#0 /media/sf_Sites/tempus/app/Acme/Repositories/DbProjectRepository.php(64): Illuminate\Exception\Handler->handleError(8, 'Undefined varia...', '/media/sf_Sites...', 64, Array)
#1 /media/sf_Sites/tempus/app/controllers/ProjectController.php(40): Acme\Repositories\DbProjectRepository->getProjectTasks('55')
#2 [internal function]: ProjectController->projectrelatedtasks('55')
#3 /media/sf_Sites/tempus/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(231): call_user_func_array(Array, Array)
#4 /media/sf_Sites/tempus/bootstrap/compiled.php(5784): Illuminate\Routing\Controller->callAction('projectrelatedt...', Array)
#5 /media/sf_Sites/tempus/bootstrap/compiled.php(5772): Illuminate\Routing\ControllerDispatcher->call(Object(ProjectController), Object(Illuminate\Routing\Route), 'projectrelatedt...')
#6 /media/sf_Sites/tempus/bootstrap/compiled.php(4971): Illuminate\Routing\ControllerDispatcher->dispatch(Object(Illuminate\Routing\Route), Object(Illuminate\Http\Request), 'ProjectControll...', 'projectrelatedt...')
#7 [internal function]: Illuminate\Routing\Router->Illuminate\Routing\{closure}('55')
#8 /media/sf_Sites/tempus/bootstrap/compiled.php(5330): call_user_func_array(Object(Closure), Array)
#9 /media/sf_Sites/tempus/bootstrap/compiled.php(4996): Illuminate\Routing\Route->run(Object(Illuminate\Http\Request))
#10 /media/sf_Sites/tempus/bootstrap/compiled.php(4984): Illuminate\Routing\Router->dispatchToRoute(Object(Illuminate\Http\Request))
#11 /media/sf_Sites/tempus/bootstrap/compiled.php(717): Illuminate\Routing\Router->dispatch(Object(Illuminate\Http\Request))
#12 /media/sf_Sites/tempus/bootstrap/compiled.php(698): Illuminate\Foundation\Application->dispatch(Object(Illuminate\Http\Request))
#13 /media/sf_Sites/tempus/bootstrap/compiled.php(7706): Illuminate\Foundation\Application->handle(Object(Illuminate\Http\Request), 1, true)
#14 /media/sf_Sites/tempus/bootstrap/compiled.php(8309): Illuminate\Session\Middleware->handle(Object(Illuminate\Http\Request), 1, true)
#15 /media/sf_Sites/tempus/bootstrap/compiled.php(8256): Illuminate\Cookie\Queue->handle(Object(Illuminate\Http\Request), 1, true)
#16 /media/sf_Sites/tempus/bootstrap/compiled.php(10895): Illuminate\Cookie\Guard->handle(Object(Illuminate\Http\Request), 1, true)
#17 /media/sf_Sites/tempus/bootstrap/compiled.php(659): Stack\StackedHttpKernel->handle(Object(Illuminate\Http\Request))
#18 /media/sf_Sites/tempus/public/index.php(49): Illuminate\Foundation\Application->run()
#19 {main} [] []

Solution

  • You can pass arguments to the table inside the with using a closure:

    // Assume $project_id is defined as the id of the project of interest
    $user = User::with([
        'projects' => function($query) use ($project_id)
        {
            return $query->whereId($project_id);
        },
        'projects.clients',
        'projects.tasks'
    ])->find(Auth::user()->id);
    

    But you should just start with the Project itself, since the table projects has a column user_id:

    // Again, assuming $project_id is defined
    Projects::with(['clients', 'tasks'])
            ->whereUserId(Auth::user()->id)
            ->find($project_id);