2016-12-10 27 views
0

Mein Warenkorb-Modell hat:hasMany Beziehung nicht in Laravel Arbeits

public function product() { 
    return $this->hasMany('App\Product'); 
} 

Mein Produkt-Modell hat:

public function cart() { 
    return $this->belongsTo('App\Cart'); 
} 

Meine Datenbank wie folgt aussieht:

Wagen Tabelle:

enter image description here

Produkttabelle:

enter image description here

Mein Warenkorb Migration enthält:

$table->integer('product_id')->unsigned(); 
$table->foreign('product_id')->references('id')->on('products')->onDelete('cascade'); 

Mein Controller enthält:

public function index() 
{ 
    if(Auth::check())  
    { 
     $user = Auth::user(); 
     $cart = Cart::where('user_id',$user->id)->get(); 
     return view('products.cart')->withCart($cart); 
    } 
    else { 
    return view('products.cart'); 
    } 
} 

Es prüft, ob Benutzer in dann protokolliert wird Holen Sie sich Details von allen Warenkorb, wo die Benutzer-ID mit dem aktuellen Benutzer übereinstimmt. Das funktioniert.

Aber wenn ich gehen Seite product.cart Ich versuche:

@foreach($cart->product as $p) 
    {{dd($p->name)}} 
@endforeach 

ich Fehler:

Undefined property: Illuminate\Database\Eloquent\Collection::$product (View: D:\wamp64\www\ecommerce\resources\views\products\cart.blade.php) 

Können Sie mir sagen, wie von Produkten Tisch bekommen Wert mit diese Beziehung.

Vielen Dank!

Edit:

Nach verschiedenen Verfahren versucht, ich habe:

Wagen Modell:

public function product() { 

     return $this->hasMany('App\Product','id','product_id'); 
    } 

Warenkorb Controller:

public function index() 
    { 
     if(Auth::check())  
     { 
      $user = Auth::user(); 
      $cart = Cart::where('user_id',$user->id)->first(); 

      return view('products.cart')->withCart($cart); 
     } 
     else { 
      return view('products.cart'); 
     } 
    } 

Jetzt bin ich in der Lage zu bekommen das erste Produkt, das passt mit ID zusammen.

Gibt es eine Möglichkeit, alle Produkte zu erhalten, die Spiele

+0

Das Speichern der Produkte in einer Warenkorb-Tabelle ist nicht wirklich ein guter Weg zu gehen. Ich würde den Inhalt des Einkaufswagens in der Sitzung speichern. –

+0

Die Umkehrung von 'hasMany' ist' goesTo'. Sie müssen das verwenden. Verweisen Sie auf [Dokumente] (https://laravel.com/docs/5.3/eloquent-relationships). Meine Vermutung ist, es sollte sein _Produkt gehört zu einem Wagen_. – linuxartisan

+0

@linuxartisan nach dem Wechsel zu 'gehört zu' gleichen Fehler – Phoenix

Antwort

0

Sie verwenden $...->get() kehrt Sammlung. Verwenden Sie stattdessen first().

$cart = Cart::where('user_id',$user->id)->first(); 
if($cart) { 
    return view('products.cart')->withCart($cart); 
} else { 
    abort(404); 
} 
+0

Ich bekomme Fehler 'SQLSTATE [42S22]: Spalte nicht gefunden: 1054 Unbekannte Spalte products.cart_id in Where-Klausel (SQL: Wählen Sie * aus Produkten, wo products.cart_id = 1 und products.cart_id ist nicht null)' – Phoenix

+0

Hmm, Sie sollte viele zu viele statt hasMany. Oder behalten Sie Ihren alten Code und ersetzen Sie hasMany mit eins zu eins (hasOne). Ich benutze viele zu viele (anstelle der Warenkorb Tabelle, verwenden Bestellungen Tabelle direkt zu speichern Bestellungen mit neuen Spalte 'is_paid' oder' is_accepted') – trinvh

0

auf Benutzer des Modells gehen:

public function products() 
{ 
    return $this->hasManyThrough('App\Product', 'App\Cart'); 
} 

nun in Ihrem Controller finden Sie den angemeldeten Benutzers Wagen holen. Und gib es an die Aussicht weiter. B.

return view('cart.show', ['cart' => Auth::user()->cart]); 

Dann wird Ihre Foreach wie erwartet funktionieren.

PS: Möglicherweise müssen Sie IDs für die hasManyThrough-Beziehung angeben, wenn Sie nicht die Konvention für die Benennung von Datenbanktabellen verwenden. Modell-Singular (Produkt) zu pluralisierten Tabellen (Produkten).

0

Probieren Sie den folgenden Code aus.

In Ihrem Warenkorb Model

public function product(){ 
    return $this->belongsTo('App\Product','id','product_id') 
} 

in Ihrem Controller

$cart = Cart::where('user_id',$user->id)->first(); 
+0

Ich bekomme Fehler SQLSTATE [42S22]: Spalte nicht gefunden: 1054 Unbekannte Spalte 'Produkte .product_id 'in' Where-Klausel '(SQL: wähle * aus 'products' wo' products'.product_id' = 1 limit 1) – Phoenix

0

In Ihrem Warenkorb Modell benötigen Sie Beziehung für Produkte angeben:

public function products(){ 
    //return $this->hasMany('App\Product'); should be changed to 
    return return $this->belongsToMany('App\Product','carts_products', 'cart_id', 'product_id'); // see link to tutorial below. 
} 

Mit dieser Beziehung Sie aktivieren können Lazy Loading von Produkten, wenn Sie ein Cart-Objekt für den Benutzer erhalten, um dies in Ihrem Controller zu erreichen eed:

public function index() 
{ 
    if(Auth::check())  
    { 
     $user = Auth::user(); 
     $cart = Cart::with('products')->where('user_id',$user->id)->first(); 
     //we get cart via first() as we need single instance of cart not an array of carts, 
     //even there's only one cart per user get() will return an array of one item 
     // with('products') lazyloads linked products to cart as you get cart instance 
     return view('products.cart')->with('cart',$cart); 
    } 
    else { 
    return view('products.cart'); 
    } 
} 

Später in der Ansicht Sie werden in der Lage sein, faul geladenen Produkte Array iterieren wie:

@foreach($cart->products as $p) 
{{dd($p->name)}} 
@endforeach 

Denken der Beziehungen zwischen den Modellen in Bezug auf die Erstellung, wie Sie auf sie zugreifen werden in In der Zukunft müssen Sie nicht alle Beziehungen zwischen Objekten überspezifizieren, da nur einige davon wirklich im Code verwendet werden. Hoffe, es wird dir helfen.

EDIT

Änderung Beziehung Typ belongsToMany und es sollte funktionieren, wie Ihr Warenkorb viele Produkte hat. Sie müssen immer noch eine einzige Cart-Instanz mit der ersten() Methode erhalten. Die verwandten Produkte werden nach Bedarf geladen.

Wichtig:

Schauen Sie sich das Tutorial https://scotch.io/tutorials/a-guide-to-using-eloquent-orm-in-laravel, wie Sie Ihr Datenbankschema ändern müssen, dies zu erreichen. Derzeit können Sie in Ihrem Schema nur ein Produkt pro Warenkorb haben. Schauen Sie in diesem Beispiel, wo sie Picknicks zu Bären Tabelle erstellen bears_picnics - in Ihrem Fall haben Sie Produkte zu Wagen Tabelle carts_products Spaziergang durch Tutorial in Ihrem Fall cart ist bear und picnics sind products.

Beispiel carts_products Schema:

Schema::create('carts_products', function(Blueprint $table) 
    { 
     $table->increments('id'); 

     $table->integer('cart_id'); // the id of cart 
     $table->integer('product_id'); // the id of product in cart 

     $table->timestamps(); 
    }); 

product_id Feld entfernen Sie Schema karren, wie es in einem solchen Fall nutzlos. Wenn Sie eine Kaskadenlöschung benötigen, geben Sie sie in der Tabelle carts_products an.

Happy Coding! Danke für eine gute Frage :), die uns dazu bringt, tiefer zu forschen.

+0

Ich erhalte Fehler SQLSTATE [42S22]: Spalte nicht gefunden: 1054 Unbekannte Spalte 'Produkte. cart_id 'in' where clause '(SQL: wähle * aus 'products' wo' products.'cart_id' in (1)) – Phoenix