2017-10-30 3 views
0

Meine Viele-zu-viele-Beziehungen speichern Daten nur einmal für jedes Element, und ich kann den Fehler nicht finden, wenn ich mehrere Attribute an mehrere Elemente anschließe.Laravel 5.5 Pivot Viele-zu-Viele speichert nur einmal

Hier sind meine Modelle:

Artikel

<?php 
    ... 
    class Item extends Model 
    { 

     protected $fillable = [ 
      'external_id', 
      'url', 
      'created_at', 
      'updated_at' 
     ]; 

     /** 
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany 
     */ 
     public function attributes() 
     { 

      return $this->belongsToMany(AttributeValue::class); 
     } 

    } 

Attribut

<?php 
    ... 
    class Attribute extends Model 
    { 

     protected $fillable = [ 
      'name' 
     ]; 

     /** 
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany 
     */ 
     public function values() 
     { 

      return $this->belongsToMany(AttributeValue::class); 
     } 

    } 

Attribute

<?php 
    ... 
    class AttributeValue extends Model 
    { 

     protected $fillable = [ 
      'attribute_id', 
      'name', 
     ]; 

     /** 
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany 
     */ 
     public function items() 
     { 

      return $this->belongsToMany(Item::class); 
     } 


     /** 
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo 
     */ 
     public function attribute() 
     { 

      return $this->belongsTo(Attribute::class); 
     } 

    } 

Wie Sie sehen können, versuche ich, Attribut und seine Werte für besseren Zugriff auf die einzelnen Werte wie $item->attributes() oder $attribute->values() zu trennen.

Aussehen Meine Migrationen wie folgt aus:

Artikel

<?php 
    ... 
    class CreateItemsTable extends Migration 
    { 

     public function up() 
     { 
      Schema::create('items', function (Blueprint $table) { 
       $table->increments('id'); 
       $table->string('external_id'); 
       $table->string('url'); 
       $table->timestamps(); 
     } 
    } 

Attribute

<?php 
    ... 
    class CreateAttributesTable extends Migration 
    { 

     public function up() 
     { 
      Schema::create('attributes', function (Blueprint $table) { 
       $table->increments('id'); 
       $table->string('name'); 
       $table->timestamps(); 
     } 
    } 

Attributwerte

... und last but not least, die Pivot-Tabelle mit Jeffrey Way erstellt kühlen Laravel Extended Generators

Attributwert Artikel Schwenk

<?php 
    ... 
    class CreateAttributeValueItemPivotTable extends Migration 
    { 

     public function up() 
     { 
      Schema::create('attribute_value_item', function (Blueprint $table) { 
       $table->integer('attribute_value_id')->unsigned()->index(); 
       $table->foreign('attribute_value_id')->references('id')->on('attribute_values')->onDelete('cascade'); 

       $table->integer('item_id')->unsigned()->index(); 
       $table->foreign('item_id')->references('id')->on('items')->onDelete('cascade'); 

       $table->primary([ 'attribute_value_id', 'item_id' ]); 
    }); 
     } 
    } 

Ich weiß, das ist eine Menge Code ist aber Ich denke, das ist notwendig, um mir bei diesem Problem zu helfen.

Stellen Sie sich vor, ich Objekte für verschiedene Elemente mit Attributen wie Marke bekommen, Größe, Höhe usw.

Wenn ich versuche, sie zu meinem Pivot-Tabelle zu befestigen wie

$items = $this->getExternalItemsObject(); 

... 

foreach($items as $item) { 

    $attributes = $item->Attributes->AttributesValueList; 

    foreach ($attributes as $attribute) 
    {   

     $itemAttribute = Attribute::firstOrCreate([ 'name' => $attribute->Name ]); 

     $itemAttributeValue = AttributeValue::firstOrCreate(
      [ 'name' => $attribute->Value[0] ], 
      [ 'attribute_id' => $itemAttribute->id ] 
     ); 

     $itemAttributeValue->items()->attach($item->id); 
    } 

Nun, die beim Schleifen Durch den ersten Punkt funktioniert alles gut. Alle Attribut-IDs werden in der Pivot-Tabelle mit der zugehörigen Element-ID gespeichert. Aber für den zweiten, dritten, n-ten Gegenstand, der manchmal die gleichen Attribute wie Marke (sagen wir Nike oder so ähnlich) hat, werden die Relationen übersprungen und nicht gespeichert.

Dies ist wirklich kurios und ehrlich gesagt treibt mich ein bisschen verrückt.

Antwort

1

In Ordnung, wie es scheint, habe ich nicht die richtigen Konventionen für die Benennung von Pivot-Tabellen.

So fügte das zweite Argument belongsToMany() Methode es gelöst.

Dies ist, wie es auszusehen hat: zu

... 

return $this->belongsToMany(AttributeValue::class, 'attribute_value_item'); 

... 

... und das gleiche gilt für die im Zusammenhang many-to-many-Modelle.

Zusätzlich hatte ich ->syncWithoutDetaching([$item->id]) statt ->attach($item->id) zu verwenden.