2017-08-15 19 views
0

を更新した場合、私は、コントローラでこのようなコードを持っているモデルを保存するために実装します$ tourist_to_updateがすでにDBにあるものと等しい場合。Laravel雄弁イベントは

私は$配列に$ tourist_to_updateを保存したい[]「ツーリスト」テーブル内のレコードが更新されている場合にのみ、(新しいレコードが作成されるか、または何も変化しません)

私が知っているように、そこに私のニーズにマッチするように見える更新更新イベントを、持っている雄弁イベントhttps://laravel.com/docs/5.4/eloquent#eventsがある。

問題は、私は&はいくつかのチュートリアルを読んで、まだそれらを使用する方法を理解していない見ている。

私はどのように対レジスタ観光モデルで雄弁イベントを知っている:

protected static function boot() 
{ 
    parent::boot(); 

    static::updating(function ($model) { 

    }); 
} 

誰もが、私は雄弁イベントに私の目標をachiveできる方法を説明してもらえますか?

ありがとうございます。

+0

ですから、更新されたレコードのみを含む新しい配列 '$ array'を作成したいですか? – TheFallen

+0

@ TheFallen yes :)正確に! –

答えて

1

これは、もう少し複雑なアプローチですが、データが変更された更新されたレコードのみを取得したい場合、これは機能しています。あなたのコントローラーメソッドでは:

app()->singleton('touristsCollector', function ($app) { 
    $collector = new \stdClass; 
    $collector->updated = []; 

    return $collector; 
}); 

for($i = 0; $i < $number_of_tourists; $i++) { 
    $tourist = Tourist::updateOrCreate(
     ['doc_number' => $request['doc_number'][$i]], 
     $tourist_to_update 
    ); 
} 

$collector = resolve('touristsCollector'); 
var_dump($collector->updated); // Only updated tourists which have data changed 

これは、基本的にモデルイベントから更新されたすべての観光客を収集する標準のPHPクラスをアプリケーションコンテナに追加します。お使いのモデルでは、これを追加します。

protected static function boot() 
{ 
    parent::boot(); 

    static::updated(function ($model) { 
     $collector = resolve('touristsCollector'); 
     $collector->updated[] = $model; 
    }); 
} 

これは、基本的にそれのいくつかのプロパティが更新された場合にのみ、観光モデルを追加し、アプリケーションコンテナからPHPクラスを取得します。

+0

うわー、これは私が探していたものです。私はいくつかの質問があります:私は 'static:updated'を 'static:updating'に変更しても差は見られません。それでは違いはありますか?:) –

+0

'app() - > singleton'と '\ stdClass'についての詳細はどこですか? –

+1

@SergejFomin、 'updated'イベントはプロパティが同じであっても起動します。データの変更がある場合にのみ起動されるので、 'updated'イベントが必要です。 – TheFallen

0

モデルは、プロパティwasRecentlyCreatedを作成した場合はtrueに設定されますので、このモデルは、新規または更新されているかどうかをチェックする方法です。

$updated = []; 

for($i = 0; $i < $number_of_tourists; $i++) { 
    $currentTourist = ['doc_number' => $request['doc_number'][$i]]; 
    $tourist = Tourist::updateOrCreate($currentTourist, $tourist_to_update); 

    if ($tourist->wasRecentlyCreated) { 
     continue; // Go to next loop if this tourist was created now 
    } 

    $updated[] = $tourist; 
} 
+0

ありがとう、TheFallen。しかし、私は問題があると思う。 'updateOrCreate'は、更新と作成に加えて、第3の動作を持っています。 3)$ tourist_to_updateが既にDBにあるものと等しい場合は、レコードは変更しないでください。私はあなたがコードを更新したり、作成する必要はありませんすでに更新された[]配列には、データベースにある観光客を追加すると思います。私はあなたのコードを実装しました。はい、それは配列$更新されていない観光客を追加します...: –

+1

@SergejFomin、あなたは正しいです、更新されたものだけを取得するには、 'updated_at'タイムスタンプを現在の時刻と比較したり、他の回答をチェックしてください。 – TheFallen

0

観光テーブルの行が更新されたときに常に特定のコードを実行する場合は、updatedまたはcreateの呼び出しを受信するようにobserverを作成することをおすすめします。

<?php 

namespace App\Observers; 

use App\Tourist; 

class TouristObserver 
{ 
    /** 
    * Listen to the User created event. 
    * 
    * @param \App\User $user 
    * @return void 
    */ 
    public function created(Tourist $user) 
    { 
     // this will always trigger when you created a new entry 
    } 

    /** 
    * Listen to the User deleting event. 
    * 
    * @param \App\Tourist $user 
    * @return void 
    */ 
    public function updated(Tourist $user) 
    { 
     // this will always trigger when actually a row was updated 
    } 
} 

あなたがしなければならないのは、このようなAppServiceProviderでオブザーバを登録することである。

public function boot() 
{ 
    Tourist::observe(\App\Observer\TouristObserver::class); 
}