// CartProduct
public function product(): HasOne
{
return $this->hasOne(Product::class);
}
// in code
Cart::query()
->with([
'cartProducts.product' => [
'attribute1',
'attribute2',
'option1',
'option2',
],
])
->get();
Apr 28, 2023
19
Level 1
N+1 problem relationships using repeated tables
Hi, I've been trying to figure out how to properly eager load and solve a N+1 problem I'm having in a ecommerce project.
I'm using the Laravel N+1 Query Detector, and when loading the cart page, it show's this alert:
Found the following N+1 queries in this request:
Model: App\Models\Product => Relation: App\Models\ProductAttribute - You should add "with('AppModelsProductAttribute')" to eager-load this relation.
Model: App\Models\Product => Relation: App\Models\ProductAttributeOpt - You should add "with('AppModelsProductAttributeOpt')" to eager-load this relation.
My current struture is: Cart Model -> CartProduct Model -> Product Model, this having 4 relationships:
public function attribute1() {
return $this->hasOne(ProductAttribute::class, 'id', 'product_att1_id');
}
public function attribute2() {
return $this->hasOne(ProductAttribute::class, 'id', 'product_att2_id');
}
public function option1() {
return $this->hasOne(ProductAttributeOpt::class, 'id', 'product_opt1_id');
}
public function option2() {
return $this->hasOne(ProductAttributeOpt::class, 'id', 'product_opt2_id');
}
And the CartProduct has this relatioship with Product:
public function product() {
return $this->hasOne(Product::class, 'id', 'product_id')
->with('parent', function ($query) {
$query->whereNotNull('id');
})
->with('attribute1', function ($query) {
$query->whereNotNull('id');
})
->with('option1', function ($query) {
$query->whereNotNull('id');
})
->with('attribute2', function ($query) {
$query->whereNotNull('id');
})
->with('option2', function ($query) {
$query->whereNotNull('id');
})
;
}
Since the attributes and options relationships are optional, I'm using whereNotNull to only eager load when those are present, but I'm still having this N+1 problem.
Removing the "withs" from this last relatioship changes the alert, asking to eager load attribute2 and option2.
Any suggestions on how to fix this?
Please or to participate in this conversation.