Hi I'm trying to query three tables from my client controller, a quick overview of my database, users
clients
projects
tasks
a user
hasMany
clients
, projects
and tasks
and these projects
and tasks
also belongTo
a client
.
So I'm in the Client Controller and I want to query the logged in users
clients
projects
, however when I try to do this I get thrown an undefined method error:
BadMethodCallException Call to undefined method Illuminate\Database\Query\Builder::user()
I'm not sure why this is occurring, I queried the clients projects separately and it works fine but when I add an additional layer it throws me the above error.
I'm a newbie on Laravel 4 so would appreciate some guidance to help rectify the error and help me understand where I'm going wrong.
My code is below:
ClientController.php
public function show($id)
{
$client = Client::find($id);
$client->load(array('projects' => function($query)
{
// With the clients for each project
$query->with('user');
}));
// Create an empty array
$associated = array();
// Loop through client projects
foreach($client->projects as $project):
// Loop through project users
foreach($project->user as $user):
// Check if the user is the same as the logged in user
if($user->id == Auth::user()->id){
// If yes add the $project to the $associated array
array_push($associated, $project);
}
endforeach;
endforeach;
// show the view
return View::make('clients.show')
->with('client', $client);
}
clients/show.blade.php
<?php $clients = $client->projects; ?>
@if (Auth::check())
@if (count($clients) > 0)
@foreach ($clients as $project)
<div class="one-third column">
<div class="projects">
<ul class="data">
<li><label>Project Name: </label><a class="btn btn-small btn-success" href="{{ URL::to('project/' . $project->id.'/show' ) }}"> {{ $project->project_name }}</a></li>
<li><label class="titletoggle">Project Brief <p>(click to toggle)</p></label><p class="brief">{{ $project->project_brief }}</p></li>
</ul>
<ul class='buttonslist'>
<li><button><a href="{{ URL::to('project/' . $project->id . '/edit') }}">Edit Project</a></button></li>
<li><button><a href="/task/create">Create Task</a></button></li>
<li><button><a href="/task/view/">View Tasks</a></button></li>
</ul>
</div>
</div>
@endforeach
@else
<h3>You have no projects click <a href="/project/create">here to create a project</a></h3>
@endif
@endif
The problem has to do with the way you are eager loading. Specifically this part.
$client->load(array('projects' => function($query)
{
// With the clients for each project
$query->with('user');
}));
The proper way to eager load these nested relationships would be.
$client->load(array(
'projects',
'projects.user',
));
Or more simply.
$client->load('projects.user');
Or you can set up the eager loading during the initial query.
$client = Client::with('projects.user')->find($id);
You also didn't mention that projects belongs to user. This relationship will need to be defined in the Project model.
class Project extends Eloquent {
public function user()
{
return $this->belongsTo('User');
}
}
The lack of this method is probably the cause of the error message. Eloquent will forward calls to undefined methods to it's internal query builder object. The query builder object doesn't have a user() method, so that's why you get that error.