11
10

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 3 years have passed since last update.

getRouteKeyNameメソッドでLaravelのURLをID以外にする方法

Posted at

##はじめに
LaravelでWebアプリケーションを開発していると、 /discussion/17 のようにIDからURLが生成されます。

しかし、これではSEOやユーザーフレンドリーの観点から適切ではない場合もあるでしょう。
そこでIDで渡されてくる箇所を、 /discussion/hello-laravel のように文字列(ここではタイトル名のスラッグ)にする方法を紹介します。

##スラッグを使用するために
まず、URLにスラッグを使用するためには、 URLを生成する箇所URLを解釈する箇所 の2つを修正する必要があります。

##URLを生成する箇所
コントローラー内のDBに保存する箇所で新たに slug を追加します。このslugがURLのIDの代わりになる部分です。

DiscussionsController.php
public function store(Request $request)
{
  App\Discussion::create([
    'title'   => $request->title,
    'slug'    => str_slug($request->title),
    'content' => $request->content,
  ]);
}

DBに保存するためには、マイグレーションファイルを修正して新たにカラムを追加する必要があります。
URLが重複しないように unique() 制約をつけます。

create_discussions_table.php
public function up()
{
  Schema::create('discussions', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->string('title');
    $table->string('slug')->unique();
    $table->text('content');
    $table->timestamps();
  });
}

##URLを解釈する箇所
まずLaravelではどのようにURLを解釈しているのかというと、Laravelではインプリシットバインディングという機能があり、タイプヒントされた変数名とルートセグメント名が一致する場合、ルートまたはコントローラーアクションで定義されたEloquentモデルを自動的に解決してくれます。

例えば以下の場合だと、

web.php
Route::get('discussions/{discussion}', function (App\Discussion $discussion) {
  dd($discussion->toArray());
});

$discussionはApp\Discussion Eloquentモデルとしてタイプヒントされて、$discussionとURIの一部である{discussion}が一致するため、リクエストURIの対応する値と一致するIDを持つモデルインスタンスを自動的に挿入してくれます。

そのため、http://localhost/discussions/1でアクセスした際に、IDが1のDiscussionインスタンスが自動的に挿入されます。

ここでは、IDが1の箇所をタイトル名のスラッグに変更したいので、Discussionモデル内でgetRouteKeyName()を使用して、変更したいカラム名でオーバーライドしてあげます。

Discussion.php
public function getRouteKeyName()
{
  return 'slug';
}

これで、以下のレコードが生成されている場合、slugを利用したURLでアクセスすることができるようになります。

id title slug content created_at updated_at
1 Hello Laravel hello-laravel I Love Laravel 2020-01-01 00:00:00 2020-01-01 00:00:00

http://localhost/discussions/hello-laravel

11
10
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
11
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?