Reputation: 6310
I am trying to utilize Laravels eagerlaoding functionality, but it doesn't at all behave like expected.
I've tried following the official examples, but I cannot reproduce their behavior.
I have a Product
class which hasMany('OrderLine')
meaning actual orders for this product.
I'd like to eagerload the lines, when displaying the products and their orders count, so I do this:
$products = Product::with('OrderLines')->get();
foreach($products as $product) {
var_dump($product->orderlines->first());
};
This should work fine, right?
Well, when I check the SQL log, this happens:
[SQL] select * from "products"
bindings: []
time: 0.71 milliseconds
[SQL] select * from "order_lines" where "order_lines"."product_id" in (?, ?, ?, ?)
bindings: [2,3,4,5]
time: 0.79 milliseconds
[SQL] select * from "order_lines" where "order_lines"."product_id" = ?
bindings: [2]
time: 0.32 milliseconds
[SQL] select * from "order_lines" where "order_lines"."product_id" = ?
bindings: [3]
time: 0.3 milliseconds
[SQL] select * from "order_lines" where "order_lines"."product_id" = ?
bindings: [4]
time: 0.31 milliseconds
[SQL] select * from "order_lines" where "order_lines"."product_id" = ?
bindings: [5]
time: 0.29 milliseconds
I can't seem to wrap my head around why Laravel/Eloquent behaves this way. First it correctly eagerloads the lines, but then it ignores the preloaded orderlines when I loop over the products...?
Upvotes: 0
Views: 74
Reputation: 111889
You should loop orderlines
this way:
foreach($products as $product) {
foreach ($product->orderlines as $ol) {
echo $ol->name;
}
}
EDIT
I've checked it and the problem is case of letters.
If your relation has name orderLines
you should use:
$products = Product::with('orderLines')->get();
foreach($products as $product) {
foreach ($product->orderLines $ol) {
echo $ol->name;
}
}
so in all places you should use orderLines
exactly the same - not in one place OrderLines
and in the other orderlines
Upvotes: 1