2016-06-17 13 views
1

Ich habe eine Tabelle mit ProduktenLaravel 4.2 n + 1 ohne eager loading

products 
------------------------------------------------ 
id product_code purchase_type quantity 
1 106    new    1 
2 107    renew   3 

und eine Preisliste für Produkte

price_list 
---------------------------------------------------------------------- 
id product_code purchase_type minimum  maximum  unit_price 
1 106    new    1   25   20 
2 106    new    26   50   16 
3 106    new    51   100   14 

Wenn ich die Produkte auf einer Seite angezeigt werden, ich brauche die angezeigt werden Preis mit der Formel

getPrice(product_code, purchase_type, quantity) for every product 

mit

foreach(Product::all() as $product){ 
    {{ $product->product_code }} 
    {{ $product->purchase_type }} 
    {{ $product->quantity }} 
    {{ PriceList::getPrice($product->product_code, $product->purchase_type, $product->quantity) }} - this one is the n+1 problem 
} 

Preisliste :: getPrice() ist so etwas wie:

public static function getPrice($productCode, $purchaseType, $quantity){ 
    return PriceList::where('product_code', $productCode) 
     ->where('purchase_type', $purchaseType) 
     ->where('minimum', '>=', $quantity) 
     ->where('maximum', '<=', $quantity) 
     ->get()->first()->unit_price; 
} 

Ich kann nicht eine effizientere Art und Weise zu finden scheinen. Und wenn ich über 1000 Produkte ausstelle, dann wird es sehr langsam. Ich kann keinen Weg finden, eifrig zu laden.

Antwort

0

ich einen Weg mit mysql gefunden,

SELECT 
    `products`.`id` AS `product_id`, 
    `products`.`product_code` AS `product_product_code`, 
    `products`.`purchase_type` AS `product_purchase_type`, 
    `products`.`quantity` AS `product_quantity`, 
    `price_list`.`product_code` AS `price_list_product_code`, 
    `price_list`.`purchase_type` AS `price_list_purchase_type`, 
    `price_list`.`minimum` AS `price_list_minimum`, 
    `price_list`.`maximum` AS `price_list_maximum`, 
    `price_list`.`unit_price` AS `price_list_unit_price` 
FROM 
    `products` 
LEFT JOIN `price_list` ON `products`.`product_code` = `price_list`.`product_code` 
AND `products`.`purchase_type` = price_list.purchase_type 
AND `products`.`quantity` >= price_list.minimum 
AND `products`.`quantity` <= price_list.maximum 
ORDER BY 
    `products`.`id` ASC 

http://sqlfiddle.com/#!9/5d6ac/2

0

Es ist keine gute Idee, das Modell aus der internen Schleife aufzurufen, um Daten zu erhalten.

Anstatt dies zu tun, folgen Sie unten.

Sie sollten zwischen den Tabellen Product und PriceList definieren.

In Modell product.php

public function price_list(){ 
    return $this->hasMany('PriceList','product_code'); 
} 

In Modell PriceList.php

public function product(){ 
    return $this->belongsTo('Product','product_code'); 
} 

In Controller-Datei

$products = Product::with('price_list')->get(); 
return View::make('your_view')->with('products', $products); 

In View File (Datei muss extention haben .blade.php unter Syntax zu verwenden)

@foreach($products as $product) 
    {{ $product }} 
@endforeach 

Hinweis: - Print $ Produkte in Controller Ergebnisse zu überprüfen.

+0

Versuchte $ products = Produkt :: mit ('price_list') -> get(); Ich muss das Produkt zurückgeben, das alle 3 Bedingungen entspricht: getPrice ($ productCode, $ purchaseType, $ quantity) Es sollte die price_list mit mindestens 1 und maximal 25 und purchase_type Renew-Lizenz zurückgeben, sondern stattdessen mindestens 250 maximal 499 zurückgegeben eine Möglichkeit, die Bedingung wie $ products = Product :: mit ('price_list', $ query-> wo ('price_list.product_code', 'product.product_code') -> where ('price_list.purchase_type, product.purchase_type) anzugeben) -> bekommen(); oder etwas ähnliches? – George

Verwandte Themen