例
ルートに指定される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種類あり、明示的結合と暗黙的結合がある。
今回は明示的結合で魔改造していく。
RouteServiceProvider
のboot()
の中に追記する。
$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から削除しないとコントローラーの引数に入ってきてしまうため。
このように明示的結合を使えば好きなインスタンスをコントローラーの引数に渡してあげることができる。