2015-03-08 16 views
6

Ho un progetto laravel, e ho bisogno di fare alcuni calcoli immediatamente dopo aver salvato un modello e attaccato alcuni dati ad esso.Eloquent attach/detach/sync attiva qualsiasi evento?

C'è qualche evento che viene attivato in laravel dopo aver chiamato attach (o staccare/sincronizzare)?

+1

Per quanto ne so non c'è nessun evento chiamato. Tuttavia è possibile utilizzare i gestori di eventi per sparare uno – cleanunicorn

+0

Grazie! @hydrarulz sì ma dovrò preoccuparmi di sparare manualmente ogni volta che uso attaccare su quel modello specifico, non ottimale –

risposta

18

No, non ci sono eventi di relazione in Eloquent. Ma si può facilmente farlo da soli (Dato ad esempio Ticket belongsToMany Component relazione):

// 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)); 
    } 
} 

oggetto evento semplice come questo:

<?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; 
    } 
} 

poi un ascoltatore di base come ad esempio sensata:

// 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()); 
    }); 

e il loro utilizzo:

$ php artisan tinker 

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

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

detached: 4 
attached: 1,3 
=> null 

Ovviamente puoi farlo senza creare oggetti Event, ma in questo modo è più conveniente, flessibile e semplicemente migliore.

+0

grazie ottima risposta! quindi dovrò usare la mia nuova funzione definita (syncComponents nel tuo esempio) con il mio modello durante la sincronizzazione? –

+1

Sì, è vero. –

+0

ok, questo è in effetti ciò che volevo evitare, per riscrivere ogni file in cui viene chiamato attach/sync. Ma mi hai dato un'ottima risposta amico! –

2

passaggi per risolvere il problema:

  1. Crea rapporto personalizzato BelongsToMany
  2. In BelongsToMany relazioni con clienti di override attaccare, staccare, di sincronizzazione e updateExistingPivot metodi
  3. nel metodo di invio eventi desiderati sovrascritto. Metodo
  4. Override belongsToMany() nel modello e restituire il rapporto personalizzato non predefinito relazione

e il gioco è fatto. Ho creato il pacchetto che già lo fa: https://github.com/fico7489/laravel-pivot

Problemi correlati