A stack overflow user answered me two ways to return each person’s furniture in a ‘one to many’ relationship. This worked well.
My question is to know the difference in the two ways. The advantages and disadvantages of each way.
IMPORTANT: Laravel Version: 5.8
First solution:
public function showPersonFurnitures($id) { $person = Person::with('furnitures')->findOrFail($id); $furnituresOfEachPerson = $person->furnitures; //<----- return response()->json($furnituresOfEachPerson); }
Second solution:
public function showPersonFurnitures($id) { $person = Person::with('furnitures')->findOrFail($id); $furnituresOfEachPerson = $person->furnitures()->get(); //<---- return response()->json($furnituresOfEachPerson); }
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
The given answers are vague and incomplete, so here’s a better explanation hopefully:
Situation 1 $person->furnitures()
: When you call any of a model’s relations as a function, you get an (incomplete) query object for that particular relation. That means whenever you call $person->furnitures()
, any additional functions you chain on this result like ->where()
are actual SQL operators and directly modify the query. In order to complete the query, you should call ->get()
(or a function like ->pluck()
) at the end to retrieve the actual data.
Situation 2 $person->furnitures
: When you call any of a model’s relations as a property, you retrieve the complete relation collection for that model. This means that $person->furnitures
lazy-loads the collection if it is not available on the model yet. Any additional functions you chain on this result like ->where()
will act on the PHP collection.
By using Person::with('furnitures')...
you make sure that the relation is already loaded (Eager Loaded) after the findOrFail()
call. You might note that this is not particularly useful with respect to loading 1 model (since you might just as well call $person->furnitures
whenever you need it), but the important thing to remember here is that this with()
method is extremely useful when you are retrieving collections of a model, like $persons = Person::where('activated', 1)->with('furnitures')->get()
. This last query only executes 2 queries: 1 for retrieving persons, and 1 for retrieving all furniture related to these persons.
Method 2
Overall, the difference for those 2 methods are not huge and you will get the same result, except:
$person->furnitures
uses relationships, quite similar to eager loading that it retrieves data based on the One to Many relationship.$person->furnitures()->get()
is implemented from the perspective of collection, which is why it has the syntax of querying a collection.
Method 3
They are same, but $person->furnitures
requires extra steps to understand tha this is relation, and finally call $person->furnitures()->get()
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0