LaravelでrouteのURLをDBの値で制御する


#やること
DBの値を参照してURLを制御する。
#結論
- route は collection が参照できるので、collectionを取得したあと、正規表現に書き換える。
- `Route::get('/{pref}', 'PrefController@index')->where('pref', '('.implode('|', App\Pref::all()->pluck('read_roma')->toArray()).')');
`

#経緯
laravel では route の制御を where句で正規表現を用いるなどで行います。
この時 config で配列を用意したり、正規表現べた書きで制御することが多いですが、
マスタデータがある場合など、DBデータを参照してURLを切り分けたいときなどが結構あります。
今回その方法についてまとめておきます。


#手順
都道府県ページを作っていく手順を例に書いていきます。
例としては `/hokkaido` や `/aomori` はルーティングを行いますが、それ以外の場合は弾きたいとき。
## マスタデータを作る
こういう感じでDBを作ります。
ここは今回割愛します。

```pref_masters
+----+--------------+-----------+
| id | name         | roman     |
+----+--------------+-----------+
|  1 | 北海道       | hokkaido  |
|  2 | 青森県       | aomori    |
|  3 | 岩手県       | iwate     |
|  4 | 宮城県       | miyagi    |
|  5 | 秋田県       | akita     |
|  6 | 山形県       | yamagata  |
|  7 | 福島県       | fukushima |
|  8 | 茨城県       | ibaraki   |
|  9 | 栃木県       | tochigi   |
| 10 | 群馬県       | gunma     |
| 11 | 埼玉県       | saitama   |
| 12 | 千葉県       | chiba     |
| 13 | 東京都       | tokyo     |
| 14 | 神奈川県     | kanagawa  |
| 15 | 新潟県       | niigata   |
| 16 | 富山県       | toyama    |
| 17 | 石川県       | ishikawa  |
| 18 | 福井県       | fukui     |
| 19 | 山梨県       | yamanashi |
| 20 | 長野県       | nagano    |
| 21 | 岐阜県       | gifu      |
| 22 | 静岡県       | shizuoka  |
| 23 | 愛知県       | aichi     |
| 24 | 三重県       | mie       |
| 25 | 滋賀県       | shiga     |
| 26 | 京都府       | kyoto     |
| 27 | 大阪府       | osaka     |
| 28 | 兵庫県       | hyogo     |
| 29 | 奈良県       | nara      |
| 30 | 和歌山県     | wakayama  |
| 31 | 鳥取県       | tottori   |
| 32 | 島根県       | shimane   |
| 33 | 岡山県       | okayama   |
| 34 | 広島県       | hiroshima |
| 35 | 山口県       | yamaguchi |
| 36 | 徳島県       | tokushima |
| 37 | 香川県       | kagawa    |
| 38 | 愛媛県       | ehime     |
| 39 | 高知県       | kochi     |
| 40 | 福岡県       | fukuoka   |
| 41 | 佐賀県       | saga      |
| 42 | 長崎県       | nagasaki  |
| 43 | 熊本県       | kumamoto  |
| 44 | 大分県       | oita      |
| 45 | 宮崎県       | miyazaki  |
| 46 | 鹿児島県     | kagoshima |
| 47 | 沖縄県       | okinawa   |
+----+--------------+-----------+
```
## model を作る
上記のマスタに対応したモデルを作ります。
ここも今回のメインではないので詳細は割愛します。

```Pref.php
namespace App;

use Illuminate\Database\Eloquent\Model;

class Pref extends Model
{
    protected $table = "pref_masters";
    protected $fillable = [ "id" , "name", "roman"];
}
```
##route　を書く
結論から書くと以下で pref_masters の romanの値だけでルーティングできます。
`Route::get('/{pref}', 'PrefController@index')->where('pref', '('.implode('|', App\Pref::all()->pluck('roman')->toArray()).')');`

where句では正規表現を利用してURLを制御できます。
今回はマスタから全件データを取得し正規表現を作成することで実現しています。

少しだけ説明します。
###where句について
`where('name', '正規表現')` で、変数nameが正規表現にマッチしたときだけを対象にできます。
正規表現を以下手順で作成します。
### implode について
文字列の配列を第一引数を挟み込んで展開結合します。
詳細は[リファレンス](http://php.net/manual/ja/function.implode.php)を参照してください。
今回は`|(パイプ)`を挟み込みながら展開していくことで、
正規表現での or を表現します。
###クエリビルダについて
`App\Pref::all()->pluck('roman')->toArray())`について簡単に説明すると、

Prefモデルから全件取得(`all()`)し、
romanカラムだけを抽出し(`pluck('roman')`)、
配列にキャスト(`toArray()`)
しています。

以上で、where句内の正規表現を pref から全件データを取得したDBの値で動的に表現することができます。
これによりDBのデータをもとにルーティングを制御できます。

#まとめ
今回はroute内でDBの値を取得し、正規表現をimplodeによって作成することで、
DBの値で動的にルーティングを制御しました。

以上です。