開発者ドキュメント

ルートモデルバインディングを備えたよりクリーンなLaravelコントローラー

序章

ウェブサイトを構築するためのフレームワークまたはAPIを構築するためのコンテナー( lumen )としてのLaravelは、開発者が選択するフレームワークとして進化してきました。 Laravelには、多くの機能が追加されています。たとえば、Laravelのイベントを取り上げます。 Laravelのイベントは、以前は単純なpub-subライブラリでしたが、Laravelイベントをクライアントにブロードキャストできるようになり、リアルタイムアプリを作成できるようになりました。

しかし、それは重要なことではありませんが、今日の有名人はLaravelのルートモデルバインディングです。

ルートモデルバインディングとは

Laravelのルートモデルバインディングは、モデルインスタンスをルートに注入するメカニズムを提供します。 まだ意味がはっきりしていませんが、ここに例を示します。 データベースから投稿を取得したい場合は、次のようにすることができます。

...
// the route parameter is the id of the post
// for example http://example.com/posts/53
Route::get('posts/{id}', function ($id) {

  // we have to find the post using the $id
  $post = Post::find($id);

  // if there is no post, 404
  if (!$post) return abort(404);

  // return the view and the post
  return view('post.show', compact('post'));
});
...

この方法をさらに単純化して、

...
// the route parameter is the id of the post
// for example http://awesome.dev/posts/53
Route::get('posts/{id}', function ($id) {

  // find the post or 404 if not found
  $post = Post::findOrFail($id);

  // return the view and the post
  return view('post.show', compact('post'));
});
...

ただし、ルートモデルバインディングは、上記の両方のインスタンスを単純化することにより、余分なキーストロークを取り除くのに役立ちます。

...
// by using $post, we can inject the Post object
Route::get('posts/{post}', function ($post) {

  // we now have access to the $post object! no code necessary

  // return the view and the post
  return view('post.show', compact('post'));
});
...

これは、Laravelに注入するように指示することで可能になります Post を持っている任意のルートコントローラーにモデル化する {post} それに添付されたパラメータ。

Laravelは現在、2種類のルートモデルバインディングをサポートしています。 我々は持っています:

注:上記のルートモデルバインディングの例は明示的です。

暗黙的なモデルバインディング

明示的なモデルバインディングを見てきましたが、暗黙的なモデルバインディングの例を次に示します。

Route::get('posts/{post}', function (App\Post $post) {
  // be awesome. enjoy having the $post object
});

Laravelはそれを知るのに十分賢いです Post モデルはコントローラークロージャーに注入されています。 id ルートからパラメータを取得し、ユーザーの詳細を取得します。

投稿へのアクセスは引き続き使用して行われます http://awesome.example.com/posts/24.

モデルのルートキーの変更

暗黙的なモデルバインディングで次のデータベース列以外のデータベース列を使用する場合 id モデルを取得するときに、 getRouteKeyName Eloquentモデルのメソッド。

たとえば、 slug の代わりに id、次のことができます。

class Post extends Model {
  public function getRouteKeyName() {
    return 'slug';
  }
}

次に、を使用してルートにアクセスできます http://awesome.example.com/posts/my-post-slug それ以外の http://awesome.example.com/posts/24.

明示的なモデルバインディング

名前が示すように、Laravelにバインドするように明示的に指示する必要があります url 特定のモデルへのパラメータ。 これを行うには2つの方法があります。提供されているものを使用して、パラメータをモデルにバインドできます。 Route ファサードまたはこのバインディングを実行する app/Providers/RouteServiceProvider.php (私はこの方法を好みます)。

を使用して Route ファサード

を使用して Route パラメータをモデルにバインドするファサードでは、次のようなことができます。

Route::bind('post', 'App\Post');

また、バインディングにもっと意味を持たせることもできます。たとえば、ドラフトの場合にのみ投稿が必要な場合はどうでしょうか。 そのために、の2番目のパラメータを変更できます。 Route::bind ルートパラメータを値として取るクロージャに。

Route::bind('post', function ($value) {
  return App\Post::find($value)->where('status', '=', 'published')->first();
});

を使用して RouteServiceProvider

を使用することの唯一の違い Route ファサードと RouteServiceProvider クラスはそれです-あなたのバインディングの登録はで行われます boot の方法 RouteServiceProvider クラス(場所は app/Providers ディレクトリ)と bind メソッドはで呼び出されます $router メソッドに注入されたオブジェクト。 簡単な例

public function boot(Router $router)
{
  parent::boot($router);

  $router->bind('post', function ($value) {
    return App\Post::find($value)->where('status', '=', 'published')->first();
  });
}

ルートモデルバインディングのカスタム例外

私は多くのAPIを構築しているので、ルートモデルバインディングのカスタム例外は、実際には私のような人々にとってより便利です。 Laravelは私たちがこれを行うための簡単な方法を提供します。 まだ boot の方法 RouteServiceProvider クラス、 model 上のメソッド $router 物体。

The model メソッドは3つの引数を取ります。引数は、 bind メソッド、新しい追加で、新しい例外をスローするクロージャである3番目の引数。

$router->model($routeParameter, $modelToBind, function () {
  throw new NotFoundHTTPException;
});

結論

ルートモデルバインディングの詳細については、ドキュメントを参照してください。

うまくいけば、この小さいながらもきちんとした機能により、プロジェクトのコードを数行節約し、コントローラーをよりクリーンにすることができます。

モバイルバージョンを終了