2015-03-08 13 views
6

Ich habe ein Laravel-Projekt, und ich muss sofort einige Berechnungen durchführen, nachdem ich ein Modell gespeichert und einige Daten angehängt habe.Eloquent attach/detach/sync feuert jedes Ereignis?

Gibt es ein Ereignis, das in Laravel nach dem Aufruf von attach (oder detach/sync) ausgelöst wird?

+1

Soweit ich weiß gibt es kein Ereignis genannt. Allerdings könntest du die Ereignishandler benutzen, um einen zu feuern – cleanunicorn

+0

Danke! @hydrarulz ja, aber ich muss darauf achten, es manuell jedes Mal, wenn ich an diesem spezifischen Modell befestigen, feuern, nicht optimal –

Antwort

18

Nein, in Eloquent gibt es keine Beziehungsereignisse. Aber man kann es leicht selbst tun (Given zum Beispiel Ticket belongsToMany Component Beziehung):

// Ticket model 
use App\Events\Relations\Attached; 
use App\Events\Relations\Detached; 
use App\Events\Relations\Syncing; 
// ... 

public function syncComponents($ids, $detaching = true) 
{ 
    static::$dispatcher->fire(new Syncing($this, $ids, $detaching)); 

    $result = $this->components()->sync($ids, $detaching); 

    if ($detached = $result['detached']) 
    { 
     static::$dispatcher->fire(new Detached($this, $detached)); 
    } 

    if ($attached = $result['attached']) 
    { 
     static::$dispatcher->fire(new Attached($this, $attached)); 
    } 
} 

Ereignisobjekt als einfach:

<?php namespace App\Events\Relations; 

use Illuminate\Database\Eloquent\Model; 

class Attached { 

    protected $parent; 
    protected $related; 

    public function __construct(Model $parent, array $related) 
    { 
     $this->parent = $parent; 
     $this->related = $related; 
    } 

    public function getParent() 
    { 
     return $this->parent; 
    } 

    public function getRelated() 
    { 
     return $this->related; 
    } 
} 

dann ein Grund Zuhörer als sinnvolles Beispiel:

// eg. AppServiceProvider::boot() 
    $this->app['events']->listen('App\Events\Relations\Detached', function ($event) { 
     echo PHP_EOL.'detached: '.join(',',$event->getRelated()); 
    }); 
    $this->app['events']->listen('App\Events\Relations\Attached', function ($event) { 
     echo PHP_EOL.'attached: '.join(',',$event->getRelated()); 
    }); 

und Verwendung:

$ php artisan tinker 

>>> $t = Ticket::find(1); 
=> <App\Models\Ticket> 

>>> $t->syncComponents([1,3]); 

detached: 4 
attached: 1,3 
=> null 

Natürlich könnten Sie es tun, ohne Event-Objekte zu erstellen, aber dieser Weg ist bequemer, flexibler und einfach besser.

+0

danke große Antwort! Also muss ich meine neue definierte Funktion (syncComponents in Ihrem Beispiel) mit meinem Modell beim Synchronisieren verwenden? –

+1

Ja, das stimmt. –

+0

ok, das ist genau das, was ich vermeiden wollte, um jede Datei neu zu schreiben, in der attach/sync aufgerufen wird. Aber du hast mir eine sehr gute Antwort gegeben, Kumpel! –

2

Schritte Ihr Problem zu lösen:

  1. Erstellen von benutzerdefinierten BelongsToMany Beziehung
  2. In BelongsToMany individuelle Beziehung Überschreibung befestigen, lösen, sync und updateExistingPivot Methoden
  3. In überschriebenen Methode Dispatch gewünschten Ereignisse.
  4. Aufschalten belongsToMany() -Methode in Modell und das Rück Ihre individuelle Beziehung Beziehung nicht

und das ist es Standard. Ich habe ein Paket erstellt, das das schon macht: https://github.com/fico7489/laravel-pivot