laravelのmodelのhook

最近rubyを書くようになってrakeが便利すぎてPHPで書いてることを後悔している今日このごろだけど、相変わらずlaravel.

laravelでArdentを使うと便利、が・・ - エンジニアですよ! で、Ardentのフックを使おうと思ったんだけどArdentがダメっぽいというのを書いた。

まぁでもそもそもlaravelのhookを使えば十分だよね、という話

Model Hookのはなしはこのあたり(http://laravel.com/docs/4.2/eloquent#model-events)に書いてある。

ちゃんとドキュメントを読んでいなかったので把握していなかった。

laravelのモデルにはイベントが用意されている。用意されているのは

  • creating
  • created
  • updating
  • updated
  • saving
  • saved
  • deleting
  • deleted
  • restoring
  • restore

モデルの各イベント名のメソッドに無名関数を渡すなどでイベントフックが登録できる。

相変わらず例は引用なんだけど

User::creating(function($user)
{
    if ( ! $user->isValid()) return false;
});

これで、Userモデルがcreateされる前にこの無名関数が呼ばれるようになる。

creating, updating, saving, deleting ではfalseを返すとそのアクションはその時点でキャンセルされて実行されなくなる。

なので、Validatorに書けないような事前処理があったら(あるのか?)コントローラーに書くのではなくここで処理することができ、コントローラーが肥大化するのを防げる。

イベントフックへの登録はModelのbootメソッドで行う。

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

        User::creating(function($user)
        {
            if ( ! $user->isValid()) return false;
        });

    }

こんな感じになるはず。

これはこれで書くことが少ないうちはいいけど、フックが多い場合はモデルが大変なことになってしまう。

そこで、便利なModel Observersというのが用意されている。

その名の通り、モデルを監視してイベントがあれば対応するメソッドを呼んでくれる。

UserObserverみたいなクラスを作って、各イベントでやりたいことを同名のメソッドに定義すればいい。

class UserObserver {

    public function creating($model)
    {
            if ( ! $user->isValid()) return false;
    }


}

さっきのをObserverに移すとこういう感じ

これの登録は、呼び出す場所は同じくbootで、observeメソッドを呼ぶ

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

        User::observe(new UserObserver);
    }

これでフックはObserverにまとめられていい感じかも。