Reputation: 17
I want to implement simple teaming option to my app. I have theese tables:
users/teams /team_members/
-----/---------/------------/
id /id /id /
name /user_id /user_id /
... /... /team_id /
I have 3 models where I have defined relations:
User model:
public function teams() {
return $this->hasOne(Team::class);
}
public function teamMembers() {
return $this->hasManyThrough(Team::class, TeamMembers::class);
}
Team model:
public function user() {
return $this->belongsTo(User::class);
}
public function members() {
return $this->hasMany(TeamMember::class);
}
TeamMember model:
public function user() {
return $this->belongsTo(User::class);
}
User can only create one team, but join many teams. The problem I have is with displaying data in the frontend.
This is the query I make in the controller:
public function index(User $user) {
$teams = Team::where('user_id', auth()->user()->id )->with('members')->get();
return view('teams.index')->with('teams', $teams);
}
I have a table with the members of the current autheticated user team. I want to display the names if each member but the only thing i can do is $team->member->id and I get the ids of the users but I want to get their names too. I can do it with simple query but I dont want to make new query for every row.
This is the blade file:
@if ( $teams->count() > 0 )
@foreach ($teams as $team)
<table class="table table-striped table-sm table-responsive-lg">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Members</th>
<th scope="col">Created</th>
<th scope="col" colspan="2"></th>
</tr>
</thead>
<tbody>
<tr>
<td>{{$team->name}}</td>
<td>{{ $team->members->count('members')}} {{ Str::plural('member', $team->id) }}</td>
<td>{{ $team->created_at->diffForHumans() }}</td>
<td>
<a href="" class="btn btn-sm btn-primary">Edit</a>
</td>
<td>
<form action="" method="POST">
@method('DELETE')
@csrf
<button class="btn btn-sm btn-danger" type="submit">Delete</button>
</form>
</td>
</tr>
</tbody>
</table>
<br>
<h5>Team members:</h5>
<table class="table table-striped table-sm">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Added</th>
</tr>
</thead>
<tbody>
@foreach ($team->members as $member)
<tr>
<td>{{ $member->user->name }}</td>
<td>{{ $member->created_at->diffForHumans() }}</td>
</tr>
@endforeach
</tbody>
</table>
@endforeach
@else
<div class="container">
<h2>You do not own a team</h2>
<p class="lead text-muted">You can create your own team or join the team of other user.</p>
<p>
<a href="#" class="btn btn-primary my-2" data-toggle="modal" data-target="#createTeamModal">Create team</a>
<a href="#" class="btn btn-secondary my-2" data-toggle="modal" data-target="#joinTeamModal">Join team</a>
</p>
</div>
@endif
When I changed $team->member->id with $member->user->name it worked. It shows the names of the users but I get N+1 queries alert and I don't know how to fix it (i tried different queries and relations but it didnt work):
Upvotes: 0
Views: 1241
Reputation: 3035
You are accessing the user
relationship from each member. So lets eager load that relationship as well.
public function index(User $user)
{
$teams = Team::where('user_id', auth()->user()->id )->with('members.user')->get();
return view('teams.index')->with('teams', $teams);
}
Upvotes: 1