LoginSignup
17
5

More than 5 years have passed since last update.

Laravelのモデルでリレーションを定義するときの命名規則で迷子になった話

Posted at

前提

LaravelのModelでRelationを定義するのは非常に簡単です。Userが1:1でPhoneを持つ場合、


class User extends Model
{
    public function phone()
    {
        return $this->hasOne(Phone::class);
    }
}

こうするかとおもいます。では、Userが1:1でUserProfileを持つ場合はどう書くでしょうか。



class User extends Model
{
    public function userProfile()
    {
        return $this->hasOne(UserProfile::class);
    }
}

普通はこうでしょう。注目して欲しいのはメソッド名です。
Laravelはメソッド名はキャメルケースにするのが作法ですから、userProfileという名前は正解と言ってしまってもいいかもしれません。(UserProfileという例がそもそもよくないという指摘はやめてくだせー。ここで重要なのは単語2つであることです。)

ですが、こういう書き方をした人がいました。


class User extends Model
{
    public function user_profile()
    {
        return $this->hasOne(UserProfile::class);
    }
}

ご覧の通りスネークケースです。
なんでこんな書き方したんだ?と思いましたが、書いた本人は意図的にやっています。そして実際に使ってみると個人的には結構しっくりきてしまいました。なんででしょう?

以下、リレーションの定義をスネークケースにした意図とそれが以外と個人的にしっくりいっちゃった理由について私見を述べたいと思います。

あらかじめ言っておくとプロジェクト内で統一されていれば何も問題ない話です。。
ですが、プロジェクト内で意思統一し忘れたおかげでキャメルケースとスネークケースが混在してしまい、今のプロジェクトではどちらに寄せるべきか迷ったので、その迷いを含めてポエムにしたためておこうというのが本項の趣旨でございます。

リレーションの定義をスネークケースにした意図

彼(=以下A君)は「メソッド名はキャメルケース」ということを知らなかったわけではありません。実際にローカルスコープについては普通にキャメルケースで記述していました。

「リレーションの定義だけスネークケースにしたいなら先に伝えとけよ!勝手すんな!」

と思うかもしれませんが、A君はむしろリレーションの定義は当たり前にスネークケースだと思っていたようでした。理由はLaravelのEloquentモデルにありまちた。

カラムへのプロパティアクセスの問題

Userモデルに紐づくusersテーブルがfirst_name/middle_name/last_nameの3つのカラムを持つ場合、それらのカラムの値にアクセスするときには以下のようにします。


$user = User::find(1);
echo $user->id;
echo $user->first_name;
echo $user->midddle_name;
echo $user->last_name;

キャメルケースではなくスネークケースですね。

上記のように、Eloquentモデルはテーブルのカラム名でプロパティのようにアクセスが出来ます。しかし、一方でテーブルのカラム名は当然スネークケースで、一方でLaravelの変数名は基本的にキャメルケースが作法ということで、フレームワーク内にルールの例外が存在しちゃっているわけです。

しかし、A君はこれ例外ではなく、「テーブルレコードに関連するものについてはスネークケース」というルールと読み取ったみたいです。そのため、「リレーションの定義についてもスネークケースに統一」していたというのがA君の意図だったのでした。

しっくりいっちゃった理由

リレーションの定義は別のモデルのインスタンスを(あまり深く考えずとも)プロパティのように扱えることがメリットなはずで、そう考えるとカラムへのアクセスと同じようにスネークケースにすると非常に統一感がある気もしてきます。
実際にコードを書いている感覚としても、


$user = User::find(1);
echo $user->id;
echo $user->first_name;
echo $user->midddle_name;
echo $user->last_name;
echo $user->user_profile->nickname;

みたいに書くのは


$user = User::find(1);
echo $user->id;
echo $user->first_name;
echo $user->midddle_name;
echo $user->last_name;
echo $user->userProfile->nickname;

みたいに書くよりも記述しやすく感じました。このへんの感じ方は好みかと思います。私はスネークケースの文化で育ったのでそう感じてるだけかもしれませんし。

で、実際はどっちに寄せたの?

いくらスネークケースに書きやすさを見出したところで、混在したままであれば書きづらさはMAXでございます。なのでどちらかに統一するというのはマストであると考えました。(当たりまえ)

結果、キャメルケースに寄せました。たいした理由はありませんが、

  • ざっと見た感じスネークケースの方が修正量が少ない
  • phpcsでこのケースだけスネークケースを許可にできなそうだった。
  • 長いものに巻かれておいた方が楽

という感じでございます。作業?いまからやるんだよ!(休出)

A君の正体

1ヶ月前の私です。

17
5
3

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
17
5