2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Laravelのルートモデルバインディングを応用して自由にインスタンスを生成する

Posted at

ルートに指定されるtypeで生成するインスタンスをわけて、コントローラーのメソッドに注入したい。

Route::get('/{type}/{parent}', 'HogeController@fuge');
class HogeController extends Controller
{
    public function fuga(Parent $child)
    {
        return $child->fuga();
    }
}

abstract class Parent extends Model
{
    public function fuga() {return;}
}

class Child_1 extends Parent
{
}

class Child_2 extends Parent
{
}

明示的結合

Laravelではルートモデルバインディングは2種類あり、明示的結合と暗黙的結合がある。

今回は明示的結合で魔改造していく。

RouteServiceProviderboot()の中に追記する。

$this->app['router']->bind('parent', function ($value, $route) {

    $type = $route->parameter('type');

    if ($type === 'child_1') {
        $child = new Child_1();
    }
    if ($type === 'child_2') {
        $child = new Child_2();
    }

    $route->forgetParameter('type');

    return $child->where('id', $value)->first();
});

bind()の第一引数にはURIで指定したキーワードのどれにバインドさせるかを文字列で渡す。

今回はparentを第一引数に渡しているので、クロージャの第一引数の$valueには{parent}の箇所に実際に指定された値が入ってくる。

/child_1/500というURLでリクエストされたら$valueには500が入ってくる。

これだけだと{type}の値がとれないので、$route->parameter('type')で値を取得し、if文で生成するインスタンスを変えている。

あとは生成したインスタンスを使って、whereなりをしてかえしてあげればよい。

$route->forgetParameter('type')をしているのは、parameterから削除しないとコントローラーの引数に入ってきてしまうため。

このように明示的結合を使えば好きなインスタンスをコントローラーの引数に渡してあげることができる。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?