2015-03-08 3 views
6

У меня есть проект laravel, и мне нужно сделать некоторые вычисления сразу после того, как я сохраню модель и приложите к ней некоторые данные.Eloquent attach/detach/sync запускает любое событие?

Есть ли какие-либо события, которые запускаются в laravel после вызова attach (или отсоединения/синхронизации)?

+1

Насколько я знаю, события не называются. Однако вы можете использовать обработчики событий для запуска одного – cleanunicorn

+0

Спасибо! @hydrarulz да, но мне придется позаботиться, чтобы стрелять из него вручную каждый раз, когда я использую приложение на этой конкретной модели, а не оптимально –

ответ

18

Нет, в Красноречиве нет событий со связями. Но вы можете легко сделать это самостоятельно (Учитывая, например, Ticket belongsToMany Component связи):

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

объект события так просто, как это:

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

затем основной слушатель как целесообразный например:

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

и использование:

$ php artisan tinker 

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

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

detached: 4 
attached: 1,3 
=> null 

Конечно, вы можете сделать это без создания объектов Event, но этот способ более удобен, гибкий и просто лучше.

+0

спасибо отличный ответ! так что мне придется использовать мою новую определенную функцию (syncComponents в вашем примере) с моей моделью при синхронизации? –

+1

Да, это так. –

+0

ОК, это на самом деле то, чего я хотел избежать, чтобы переписать каждый файл, где вызывается attach/sync. Но ты дал мне очень хороший ответ! –

2

шагов, чтобы решить вашу проблему:

  1. Создание пользовательского BelongsToMany отношения
  2. В BelongsToMany пользовательских отношений переопределения присоединять, отрывать, синхронизация и updateExistingPivot методу
  3. В переопределенных методе отправка желаемых событий. Метод
  4. Override belongsToMany() в модели и вернуть пользовательское отношение не по умолчанию соотношению

и это все. Я создал пакет, который уже делает это: https://github.com/fico7489/laravel-pivot

Смежные вопросы