2016-04-08 26 views
2

Laravel 5.1

私は私のAbstractModelを拡張して、すべてのモデルのための単一のモデルオブザーバを登録しようとしている(誰が点灯\データベースを拡張している\雄弁\モデル) 。Laravelですべてのモデルのインスタンスのデフォルトのオブザーバーを登録する方法

問題は私のGenericModelObserverが、AbstractModelを継承しているモデルによって起動されたイベントを聴くことができないことです。

私がこれまでにしたことを示してみましょう。

サービスプロバイダは、その後、私は私の無地シンプルGenericModelObserver

<?php 

// app/Observers/GenericModelObserver.php 

namespace App\Observers; 

use App\Models\AbstractModel; 

class GenericModelObserver 
{ 
    public function saving(AbstractModel $model) 
    { 
     return $model->valid(); 
    } 
} 

抽象モデル

を持って作成され、コンフィグ内部/ app.php

<?php 

// app/Providers/ObserverServiceProvider.php 

namespace App\Providers; 

use App\Models\Quotation; 
use App\Models\AbstractModel; 
use App\Observers\QuotationObserver; 
use App\Observers\GenericModelObserver; 
use Illuminate\Support\ServiceProvider; 

class ObserverServiceProvider extends ServiceProvider 
{ 

    public function boot() 
    { 
     AbstractModel::observe(GenericModelObserver::class); 
     Quotation::observe(QuotationObserver::class); 
    } 

    public function register() 
    { 

    } 
} 

プロバイダ配列の最後の位置に置かれました

<?php 

// app/Models/AbstractModel.php 

namespace App\Models; 

use Illuminate\Database\Eloquent\Model; 

class AbstractModel extends Model 
{ 
    // ... 
} 

マイ・ブッキングモデル

<?php 

// app/Models/Quotation.php 

namespace App\Models; 

class Quotation extends AbstractModel 
{ 
    // ... 
} 

Quotationが保存されると、GenericModelObserverは保存イベントまたはその他のイベントをlistenできません。

特定のモデルオブザーバを持たない他のモデルにも同じことが適用されます。

これは正しい戦略ですか?私は、ブートメソッドを通してオブザーバーをすべてのモデルに結びつけるのは嫌いです。

単に親クラスを拡張しないのはなぜ

答えて

2

BaseObserverは、私が代わりにモデルを拡張するあなたのObservers

<?php namespace App\Observers; 
class Quotation extends BaseObserver{ 
    //you can override any of the methods if you wish 
} 
+0

ような何かを行うことができます。 BaseObserverを一旦アタッチして、AbstractModelを継承するすべてのインスタンスをリッスンする必要があります。私は試しましたが、あなたの答えを私が必要とするものにリンクすることができませんでした。私を啓発することができますか?仕事をありがとう。 –

3

<?php namespace App\Observers; 
class BaseObserver { 
    public function saving($model) 
    { 
     //do your thing here that apply to all observers, like caching 
    } 
} 

その後、私のキャッシュシステムに似た何かを持っていると言う - あなたを書きますオブザーバーとして働く自分自身の特性。

<?php 

namespace App\YourPackage\Traits; 

use Illuminate\Database\Eloquent\Model; 

trait Observable 
{ 
    public static function bootObservable() 
    { 
     static::updating(function (Model $model) { 
      dd('updating'); 
     }); 
    } 
} 

とモデルクラスにuse Observable;を入力して、それを使用する:
私はいくつかの基本的な形質を書いたの下。

また、あなたの学習には、どのように特性がブートしているのかを書き留めておいてください。boot[TraitClassName]メソッドを適切にブートする必要があります。
あなたの特性の中にbootメソッドを書き込まないでください、それは危険です!あなたの親モデルで

0

あなたは私の問題はBaseObserverを上書きする方法を正確でないこと

/** 
* If true will attach the observers of the parent class 
* @var bool 
*/ 
protected $shouldAttachParentObservers = true; 

public static function boot() 
{ 
    $instance = new static; 
    $instance->attachParentObservers(); 

    parent::boot(); 
} 


public function attachParentObservers() { 
    $parentClass = get_parent_class($this); 
    if(!empty($parentClass) && $this->shouldAttachParentObservers) { 
     $eventObservers = []; 
     foreach ($this->getObservableEvents() as $event) { 
      $eventObservers[$event] = ($this::$dispatcher->getListeners("eloquent.{$event}: {$parentClass}")); 
      foreach ($eventObservers[$event] as $observer) { 
       $eventName = "eloquent.{$event}: {$this::getClassName()}"; 
       $this::$dispatcher->listen($eventName, $observer); 
      } 
     } 
    } 
} 
/** 
* You may use different way to find the class name 
*/ 
public static function getClassName() { 
    return static::class; 
} 
関連する問題