Niels B.
Niels B.

Reputation: 6310

Laravel eagerloading not working

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

Answers (1)

Marcin Nabiałek
Marcin Nabiałek

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

Related Questions