Eloquent Attach/Detach/Sync Fires Any Event

eloquent-attach-detach-sync-fires-any-event
I have a laravel project, and I need to make some calculations immediately after I save a model and attach some data to it.

Is there any event that is triggered in laravel after calling attach (or detach/sync)?

  • 1
    As far as I know there is no event called. However you could use the event handlers to fire one – cleanunicornMar 8 '15 at 18:50
  •  
    Thanks! @hydrarulz yes but I will have to take care to fire it manually every time I use attach on that specific model, not optimal – Mihai Crăiță Mar 8 '15 at 20:27

2 Answers

No, there are no relation events in Eloquent. But you can easily do it yourself (Given for example Ticket belongsToMany Component relation):

// Ticket model
use AppEventsRelationsAttached;
use AppEventsRelationsDetached;
use AppEventsRelationsSyncing;
// ...

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

event object as simple as this:

<?php namespace AppEventsRelations;

use IlluminateDatabaseEloquentModel;

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

then a basic listener as a sensible example:

    // eg. AppServiceProvider::boot()
    $this->app['events']->listen('AppEventsRelationsDetached', function ($event) {
        echo PHP_EOL.'detached: '.join(',',$event->getRelated());
    });
    $this->app['events']->listen('AppEventsRelationsAttached', function ($event) {
        echo PHP_EOL.'attached: '.join(',',$event->getRelated());
    });

and usage:

$ php artisan tinker

>>> $t = Ticket::find(1);
=> <AppModelsTicket>

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

detached: 4
attached: 1,3
=> null

Of course you could do it without creating Event objects, but this way is more convenient, flexible and simply better.

原文地址:https://www.cnblogs.com/mouseleo/p/10078790.html