2013-03-25 16 views
7

Ich habe vor kurzem mit Laravel4 arbeiten begonnen. Beim Aktualisieren von Pivot-Tabellendaten stehe ich vor einigen Problemen, im Fall von vielen zu vielen Relationen.Update Pivot-Tabelle im Fall von vielen zu vielen Relation Laravel4

Die Situation ist: Ich habe zwei Tabelle: Produkt, Product. Die Beziehung zwischen ihnen ist Viele zu viele. Meine Modelle

class Product extends Eloquent { 
    protected $table = 'products'; 
    protected $primaryKey = 'prd_id'; 

    public function tags() { 
     return $this->belongsToMany('Tag', 'prd_tags', 'prta_prd_id', 'prta_tag_id'); 
    } 
} 

class Tag extends Eloquent { 
    protected $table = 'tags'; 
    protected $primaryKey = 'tag_id'; 
     public function products() 
    { 
    return $this->belongsToMany('Product', 'prd_tags', 'prta_prd_id', 'prta_tag_id'); 
    } 
} 

sind zwar Daten an die Pivot-Tabelle prd_tags Einfügen, ich habe:

$product->tags()->attach($tag->tagID); 

Aber jetzt möchte ich Daten in dieser Pivot-Tabelle aktualisieren, was ist der beste Weg, um Daten zu aktualisieren zum Pivot-Tisch. Sagen wir, ich möchte einige Tags löschen und neue Tags zu einem bestimmten Produkt hinzufügen.

+0

Haben Sie die Informationen in die Dokumente? Hilft es überhaupt ... http://four.laravel.com/docs/eloquent#working-with-pivot-tables –

+0

@PhillSparks: Ja, ich habe dieses Dokument durchgelesen. Es gibt eine Methode namens sync, um dies zu tun, die ein Array von IDs nehmen und einfügen bzw. löschen wird, aber was ist, wenn meine Pivot-Tabelle andere Attribute als die IDs beider Tabellen hat. Die Synchronisierungsmethode sollte ein Array von Objekten anstelle eines Arrays von ganzen Zahlen verwenden. – Sameer

+1

Eloquent unterstützt ein einfaches Tabellendesign, bei dem Ihre Pivot-Tabellen über ID-Spalten verfügen, mit denen auf die Zeilen verwiesen wird. Eloquent wurde nicht für andere Datenbankdesigns entwickelt, da umfangreichere ORM-Lösungen verfügbar sind. –

Antwort

5

Ich weiß, dass dies eine alte Frage, aber wenn Sie noch Interesse an der Lösung ist, hier ist es:

sagen Läßt Ihre Pivot-Tabelle ‚foo‘ und ‚bar‘ als zusätzliche Attribute hat, Sie können dies tun, Daten in diese Tabelle einfügen:

$product->tags()->attach($tag->tagID, array('foo' => 'some_value', 'bar'=>'some_other_value')); 
32

Alte Frage, aber am 13. November 2013 wurde die updateExistingPivot Methode für viele zu viele Beziehungen öffentlich gemacht. Dies ist noch nicht in der offiziellen Dokumentation.

public void updateExistingPivot(mixed $id, array $attributes, bool $touch) 

--Updates einen vorhandenen Dreh Datensatz auf dem Tisch.

Ab dem 21. Februar 2014 müssen Sie alle drei Argumente einschließen.

In Ihrem Fall (wenn Sie das Pivot-Feld ‚foo‘ aktualisieren wollten) Sie tun können:

$product->tags()->updateExistingPivot($tag->tagID, array('foo' => 'value'), false); 

Oder Sie können die letzten boolean false auf true ändern, wenn Sie den übergeordneten Zeitstempel berühren wollen .

Pull-Request:

https://github.com/laravel/framework/pull/2711/files

+2

Fantastisch.Ich wünschte, die offiziellen Dokumente würden aktualisiert, um diese Methode hervorzuheben. Dies sollte als die richtige Antwort markiert werden. Prost! –

+0

Perfekt, danke! – Guicara

+0

'öffentliche Leere', Tippfehler? – haakym

4

Eine andere Methode für diese, während sie mit Laravel Arbeits 5.0+

$tag = $product->tags()->find($tag_id); 
$tag->pivot->foo = "some value"; 
$tag->pivot->save(); 
+1

Ich muss '$ pivot-> pivot-> save();' um meine Pivot-Tabelle zu speichern. – MECU

+0

das ist eigentlich die einfachste Lösung, die ich denke. – dexterb

+0

Wenn Sie diese Methode verwenden, erhalten Sie einen Fehler: 'Indirekte Änderung der überladenen Eigenschaft hat keine Auswirkungen – JackalopeZero

0

dies ist voll Beispiel:

$user = $this->model->find($userId); 
    $user->discounts() 
     ->wherePivot('discount_id', $discountId) 
     ->wherePivot('used_for_type', null) 
     ->updateExistingPivot($discountId, [ 
      'used_for_id' => $usedForId, 
      'used_for_type' => $usedForType, 
      'used_date_time' => Carbon::now()->toDateString(), 
     ], false);