I'm building a web app using Laravel 8 and one thing I tend to struggle with is the complex relationships and accessing the data. I've started reading on hasManyThrough
relationships but I'm not convinced that's the correct way to do it for my scenario.
The app is used by travelling salesmen to check in to a location when they arrive safely.
I have three main tables:
Locations
(where they are visiting),Checkins
(where their check in data is stored, e.g. time),Users
This is where it gets a little complex and where I find myself not being able to see the wood for the trees...
As such they're all created using a belongsToMany
relationship.
Now what I'd like to do is access the user
of the check in
so I can call something similar to on my show.blade.php
:
<tbody>
@foreach($location->checkins as $checkin)
<tr>
<td>{{ $checkin->id }}</td>
<td>{{ $checkin->users()->name }}</td> // I'd like to get the users name
<td>{{ $checkin->longitude }}</td>
<td>{{ $checkin->latitude }}</td>
<td>{{ \Carbon\Carbon::parse($checkin->created_at)->format('jS F Y') }}</td>
</tr>
@endforeach
</tbody>
Is a hasManyThrough
relationship the only way I can achieve this? Or should I get a bit more creative with my controller and bring users through on their own collection?
My current Location
controller looks like this:
public function show(Location $location)
{
$page_title = "Locations";
$page_description = "Event locations.";
return view('pages.admin.locations.show', compact('page_title', 'page_description'))
->with('location' => $location);
}
Any direction or best practice advice is appreciated.
You said "Check ins have many users", you seem to want the singular user for a check-in, but currently that would result in many users. It sounds like users check-in in a many to one relationship
Also $checkin->created_at
will be by default a carbon object, so you can just go $checkin->created_at->format('jS F Y')
Also don't mix using compact
and with
, stay consistent and use only 1 as they achieve the same thing
Also $checkin->users()->name
won't work, if you use the brackets on syntax is only returns a query builder instance, which you would need to call get on like $checkin->users()->get()
, or you could use $checkin->users
which will fetch them anyway. You may want to look into using with('relation')
on query builder instances to stop N+1 queries if you want to dive a little deeper. Lastly $checkin->users()->get()->name
also won't work as your user relation is many to many which returns a collection, which again points to you should have a belongsTo relationship called user
without a pivot table