web-dev-qa-db-de.com

Laravel eloquentes Modell, wie man Daten aus der Beziehungstabelle erhält

Ich entwickle eine Laravel-Anwendung mit den folgenden eloquenten Modellen

  • Produkt hasMany ('App/Sku', 'products_id')
  • Sku Bluetooth ("App/Produkt")

Ich habe einen Controller 'ProductController', in dem der folgende Code verfügbar ist

public function index()
{    
    $products = Product::all();
    foreach($products as $product){
            $products_id = $product->products_id;
    }
}

Ich präsentiere die RESTfull-API, mit der meine Benutzer alle Produktdetails (einschließlich Skus, Versandarten usw.) abrufen können.

Angenommen, ich habe eine API GET:/products

Der Code, der alle Produktdetails abruft, wird wie folgt aussehen

public function index()
{              
      $products = Product::all();
      foreach($products as $product){
          $products_id = $product->products_id;
          $skus_data = Product::find($products_id)->skus;
      }
        // Now I have both the product details + skus which I can bundle into an array/json.
}

Nun ist meine Frage, ist diese Logik richtig? In diesem Fall befinden sich alle Logiken im Controller, da ich für jede Tabelle ein Modell mit eloquenten Modellen verwende, in dem die Beziehungen definiert sind. Gibt es eine Möglichkeit, alle Details eines Produkts/zugehörigen Modells (Produktdetails (in Tabelle 1) + Produktdetails (in Tabelle 2)) zu erhalten, anstatt die unten stehenden zu verwenden

foreach($products as $product){
    $products_id = $product->products_id;
    $skus_data = Product::find($products_id)->skus;
}

Ich bin ziemlich neu in der Entwicklung von Laravel und in eloquenten Modellen. Ich verwende das Repository-Muster für die Entwicklung, und in diesem Fall liegt die obige Logik (Produkt + Sku-Kombination).

Bitte helfen sie aus.

9
Ajeesh

Ja, Sie können die Details der Produkte und des Skus abrufen, ohne eine zusätzliche Abfrage pro Produkt zu tätigen, indem Sie eager loading .__ verwenden. (Dies wird als typisches N + 1 Abfrageproblem bezeichnet, wobei N die Anzahl der Produkte ist.) 

Angenommen, die Beziehung zwischen Ihrem Modell Product und Sku lautet:

Produkt

public function skus()
{
    return hasMany('App/Sku','products_id');
}

Um die Produktdaten zusammen mit den Sku-Daten abzurufen, können Sie die with-Methode verwenden. In Ihrem Controller:

Controller

 $products = Product::with('skus')->get();

Dann können Sie die Informationen in Ihren Ansichten auf folgende Weise abrufen:

Aussicht

foreach ($products as $product) 
{
     //$product->skus is a collection of Sku models
     dd( $product->skus );
}

Für die Repository-Frage: Wenn Sie ein Repository verwenden möchten, können Sie den eloquent-access-Teil Ihres Codes innerhalb des Repositorys ablegen. So könnten Sie zum Beispiel diese Methode im Repository haben:

ProductRepository

public function getProductsData() 
{
    //access eloquent from the repository
    return Product::with('skus')->get();    
} 

dann können Sie Ihr Repository in Ihrem Controller verwenden:

Controller

//inject the repository in the controller
public function __construct( ProductRepository $productRepo )
{
    $this->productRepo = $productRepo;
}

//use the injected repository to get the data
public function index()
{
    $products = this->productRepo->getProductsData();
}
20
Moppo

Wenn ich Ihre Frage richtig verstanden habe, können Sie eifriges Laden verwenden.

 public function index()
 {
    $products = Product::with('skus')->get();
 }

Dadurch erhalten Sie eine Reihe von Produkten, die in jedem Produktobjekt ein Skus-Array haben.

1
Fester

Wenn das Repository-Muster so verwendet wird.

public function index()
    {
      $data=$this->passportRepository->with('user')->findWhere( ['id'=>1]);
}
0