2016-10-29 4 views
1

を聴きながら:無限ループ私がやるのは、私のコードのどこかに言わせて、私は、プロパティのためLaravelアプリケーションを持っているモデルイベント

$property = new Property(); 
$property->city = "New York"; 
... 
$property->save(); 

その後、私はイベントリスナを持っている特定のイベントをリッスンしている:

$events->listen(
    'eloquent.saved: Properties\\Models\\Property', 
    'Google\Listeners\[email protected]' 
); 

そして最後にSetGeoLocationInfo.phpに私は

public function fire($event) 
{ 
    $property = $event; 
    ... 
    //get GPS data from Google Maps 

    $property->latitude = $googleMapsObject->latitude; 
    $property->longitude = $googleMapsObject->longitude; 
    $property->save(); 
} 

を持っていると私はモデルを保存するときでに行きますハンドラで呼び出されたsave()のために有限再帰が発生しました。

保存して再帰を避けるためにコードを変更して場所データを一度に埋め込むことができますか?

この場合、他のリスナーが機能しなくなる(プロパティ写真付きなど)ため、flushEventListeners()は使用できません。

+0

、保存、代わりの – Farkie

+0

を保存するだけのプロパティでsaveメソッドオーバーライドするUSE「eloquent.{$event}: {$name}」などと命名されている - モードを保存するための引数を渡します。次のようなfire():$ property-> save(Property :: SAVE_FROM_GOOGLE_FIRE);他の何かのためにもっと。 – Deep

答えて

1

この場合はおそらくsavingメソッドを使用する方が良いでしょう。

public function fire($event) 
{ 
    $property = $event; 
    ... 
    //get GPS data from Google Maps 

    $property->latitude = $googleMapsObject->latitude; 
    $property->longitude = $googleMapsObject->longitude; 
} 

他の解決策は、それがまだ設定されていない場合にのみ、GPSの場所を設定して保存するために条件を追加することになります。しかし、あなたのfire方法は次のようになりますのでsaving時にあなたは、任意のより多くのsaveメソッドを使用してはならないことに注意してください:

if (empty($property->latitude) || empty($property->longitude)) { 
    $property->latitude = $googleMapsObject->latitude; 
    $property->longitude = $googleMapsObject->longitude; 
    $property->save(); 
} 
+0

これは再帰を避けることができません – Deep

+0

@Deepなぜそう思うのですか? 2回だけ保存すると再帰はありません –

+0

プロパティ(値、存在)は保存モードではメジャー/マスターになりません – Deep

0

方法(あなたはそれのためのプロパティの定数を定義する必要があります)を保存しますプロパティ:

public function save($mode = Property::SAVE_DEFAULT) 
{ 
    switch ($mode) { 
     case Property::SAVE_FOO: 
      // something for foo 
     break; 
     case Property::SAVE_BAR: 
      // something for bar 
     break; 
     default: 
      parent::save(); 
     break; 
    } 
} 

それを呼び出す:

public function fire($event) 
{ 
    $property = $event; 
    ... 
    //get GPS data from Google Maps 

    $property->latitude = $googleMapsObject->latitude; 
    $property->longitude = $googleMapsObject->longitude; 
    $property->save(Property::SAVE_FOO); 
} 

または

$property->save(); // as default 

何が良いですか? すべての条件は1つの場所に保存されています(保存方法)。

+0

申し訳ありませんが、 '// something for foo'の代わりにDBに直接書き込むべきですか? – ademin

+0

はい、どうしてですか?あなた自身が再帰に来ました。あなたは2つの方法があります:1)再帰なしで書き直します。2)saveメソッドをオーバーライドし、必要なものをすべて書き込んでください。 – Deep

+0

私は分かりません。解決策のようには見えません。ハックのようです。カスタムイベントを作成したり、イベントでいくつかの引数を渡すことができます。 – ademin

0

ユーザーforget()を使用すると、イベントリスナーの設定を解除できます。

Event::listen('a', function(){ 
    Event::forget('a'); 

    echo 'update a '; 
    event("b"); 
}); 

Event::listen('b', function(){ 
    Event::forget('b'); 

    echo 'update b '; 
    event("a"); 
}); 

event("a"); // update a update b 

モデルイベントキーが発射時に「eloquent.updated: Foo

関連する問題