Hiding the Join Entity
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
With a Subscription, click any sentence in the script to jump to that part of the video!
Login SubscribeRefresh the homepage and... busted! In the homepage template, we're referencing ship.droidNames
. We know that this calls $starship->getDroidNames()
. But that's still trying to use the droids
property that we just deleted. Let's fix that first.
Isn't It Still a Relationship between Starship and Droid?
Now, we could patch this up by looping over $ship->starshipDroids
and grabbing the name off of each one. But hold up! Ignore this method for a minute. If you zoom out, this is still a relationship between Starship
and Droid
. So wouldn't it be nice if we could still call $ship->getDroids()
and have it return a collection of Droid
objects. Can it be done? Absolutely, my friend, absolutely.
Fixing the getDroids() Method
Use $this->starshipDroids->map()
to transform each item in the StarshipDroid
collection into a Droid
object:
// ... lines 1 - 15 | |
class Starship | |
{ | |
// ... lines 18 - 202 | |
public function getDroids(): Collection | |
{ | |
return $this->starshipDroids->map(fn (StarshipDroid $starshipDroid) => $starshipDroid->getDroid()); | |
} | |
// ... lines 207 - 257 | |
} |
We now have a getDroids()
method that once again returns a collection of Droid
objects. We rock!
Now that we have this method, down here in getDroidNames()
. Instead of using the droids
property, switch to the getDroids()
method:
// ... lines 1 - 15 | |
class Starship | |
{ | |
// ... lines 18 - 223 | |
public function getDroidNames(): string | |
{ | |
return implode(', ', $this->getDroids()->map(fn(Droid $droid) => $droid->getName())->toArray()); | |
} | |
// ... lines 228 - 257 | |
} |
Head back to the homepage template and refresh. Success! Fetching the droids for a ship is still easy. And the rest of our code didn't need to change.
Act 5: Future-Proofing Droids
Open up the Droid
entity and find getStarships()
. We haven't used this method yet, but let's fix it up too. This should return a collection of Starship
objects. Use the same map()
trick to transform the StarshipDroid
collection into a collection of Starship
objects:
// ... lines 1 - 10 | |
class Droid | |
{ | |
// ... lines 13 - 66 | |
public function getStarships(): Collection | |
{ | |
return $this->starshipDroids->map(fn (StarshipDroid $starshipDroid) => $starshipDroid->getStarship()); | |
} | |
// ... lines 71 - 119 | |
} |
Hiding the Join Entity When We Create the Relationship
There's one last thing we need to deal with. When we create the relationship, we still need to do a bit of heavy lifting by creating this join entity. It's not as simple as $ship->addDroid($droid)
. Let's tackle that in the next chapter.
Hi,
I am struggling with the custom many to many relationship. Maybe it is because of the 'friendship relation' instead of between two different entities. In my case a user can have 2 type of friendships. 1 is having a client: the user can help the client in my project. But a Client can have an Admin-like friend, the user who is helping the client.
Below first the User Entity class:
And the UserClient Entity:
After login I get the active user by:
But I never get the relations, if I use dd($activeUser), I get this:
I dont know what I am doing wrong, but trying to get the client with the getClient(), is always empty.