よ〜んです。

いきなりですが、Laravel の artisan make:model に以下のようなオプションを付けると、migration のコードも一気に作れます。

php artisan make:model Address -m

Model ができるのは理解できます。引数で Address を渡していますし

INFO  Model [app/Models/Address.php] created successfully.

でも migration はこうなります。

INFO  Migration [database/migrations/xxxx_xx_xx_xxxxxx_create_addresses_table.php] created successfully.

addresses になってる!?
ありがたいけど、どうやて変換しているのでしょうか?

末尾に雑に s を付けているだけなのか、ちゃんと辞書やルールを持っているのか、気になったので検証した後に実装を深掘りしていきます。

検証(いじわる)してみる

もし Laravel が末尾にただ s を付けているだけなら、不規則変化や単複同形で崩れるはずです。 なので、いじわるな単語を何個か試してみました。

規則的(+ves

Knife(ナイフ) → Knives

php artisan make:model Knife -m

INFO  Model [app/Models/Knife.php] created successfully.

INFO  Migration [database/migrations/xxxx_xx_xx_xxxxxx_create_knives_table.php] created successfully.

knifes ではなく knives になっています。
えらい。思ったより英語ができる。

不規則

Child(子供) → Children

php artisan make:model Child -m

INFO  Model [app/Models/Child.php] created successfully.

INFO  Migration [database/migrations/xxxx_xx_xx_xxxxxx_create_children_table.php] created successfully.

Mouse(ねずみ) → Mice

php artisan make:model Mouse -m

INFO  Model [app/Models/Mouse.php] created successfully.

INFO  Migration [database/migrations/xxxx_xx_xx_xxxxxx_create_mice_table.php] created successfully.

Man(おとこ) → Men

php artisan make:model Man -m

INFO  Model [app/Models/Man.php] created successfully.

INFO  Migration [database/migrations/xxxx_xx_xx_xxxxxx_create_men_table.php] created successfully.

ここまで来ると、さすがに末尾 s 追加だけでは説明できません。
Laravel、英語の授業をちゃんと受けています。

単複同形

Fish(さかな) → Fish

php artisan make:model Fish -m

INFO  Model [app/Models/Fish.php] created successfully.

INFO  Migration [database/migrations/xxxx_xx_xx_xxxxxx_create_fish_table.php] created successfully.

fishes ではなく fish のままでした。
単複同形まで見ているなら、かなり本格的です。

実装を追ってみる

調べると、複数形変換のルールは doctrine inflectorの英語ルールに乗っていました。

中を見ていくと、雑に s を付けているのではなく、かなりちゃんとしています。

つまり Laravel は、英単語の末尾に s を足しているだけではなく、英語の複数形変換用のルールセットを使ってテーブル名を作っていました。

Address -> addresses ぐらいならまだしも、Knife -> KnivesMouse -> Mice まで変換してくれるとは思っていませんでしたね。


俺、Inflectorがインストールされてる脳だった

Laravel の複数形変換を見ていて昔の記憶が蘇りました。

英語で、単数形から複数形への変換(???)を習うじゃないですか。 自分はアレを暗記してなかったなぁなどと思い出しました。(覚える気もなかった)

なので、まさにdoctrine inflectorのような処理フローを作っていましたね。

今思うと、英語の勉強というよりルールエンジンの設計でした。

まとめ

artisan make:model -m で migration 名が複数形になるのは、ただ末尾に s を足しているからではありませんでした。

  • Knife -> Knives
  • Child -> Children
  • Mouse -> Mice
  • Fish -> Fish

こういうところまでちゃんと吸収してくれているライブラリやフレームワークの開発者の皆さんには感謝です。

あと、今回ドキュメントを読んでいて urlize も見つけました。
今まで

hugo new content/posts/???.md

を叩く時、空白を消して - に置き換えて、みたいなことを手でやっていたんですが、使えそうだな〜とか思いました。

お  し   ま    い