目的
- LaravelにおけるDBの1対1のリレーション定義方法をまとめる
実施環境
- ハードウェア環境
項目 | 情報 |
---|---|
OS | macOS Catalina(10.15.5) |
ハードウェア | MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) |
プロセッサ | 2 GHz クアッドコアIntel Core i5 |
メモリ | 32 GB 3733 MHz LPDDR4 |
グラフィックス | Intel Iris Plus Graphics 1536 MB |
- ソフトウェア環境
項目 | 情報 | 備考 |
---|---|---|
PHP バージョン | 7.4.8 | Homebrewを用いてこちらの方法で導入→Mac HomebrewでPHPをインストールする |
Laravel バージョン | 8.6.0 | commposerを用いてこちらの方法で導入→Mac Laravelの環境構築を行う |
MySQLバージョン | 8.0.19 for osx10.13 on x86_64 | Homwbrewを用いてこちらの方法で導入→Mac HomebrewでMySQLをインストールする |
前提条件
- 実施環境に記載されている環境と近い環境が構築されていること。
前提情報
-
下記コマンドを実行してrelationアプリを作成した。
$ laravel new relation --auth
-
Auth認証で使用されるusersテーブルのIDとリンクするuser_idカラムを有するphone_numbersテーブルがあるとする。両テーブルのカラム情報を下記に記載する。
-
usersテーブル
Field Type Null Key Default Extra id bigint unsigned NO PRI NULL auto_increment name varchar(255) NO NULL email varchar(255) NO UNI NULL email_verified_at timestamp YES NULL password varchar(255) NO NULL remember_token varchar(100) YES NULL created_at timestamp YES NULL updated_at timestamp YES NULL -
phonesテーブル
Field Type Null Key Default Extra id bigint unsigned NO PRI NULL auto_increment user_id bigint unsigned NO NULL number varchar(255) NO NULL created_at timestamp YES NULL updated_at timestamp YES NULL
-
-
両テーブルのカラムに注目するとわかるようにusersテーブルとphone_numbersテーブルは1対1の関係になっている。(usersテーブルのidとphone_numbersテーブルのuser_id)
-
前述した1対1のリレーションを定義する。
概要
- usersテーブルからphonesテーブルに対するモデルファイルへの定義記載
- phonesテーブルからusersテーブルに対するモデルファイルへの定義記載
詳細
- usersテーブルからphonesテーブルに対するモデルファイルへの定義記載
-
アプリ名ディレクトリで下記コマンドを実行してUserモデルファイルを開く。
$ vi app/Models/User.php
-
下記のようにリレーションを定義する。
アプリ名ディレクトリ/app/Models/User.php<?php namespace App\Models; use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; class User extends Authenticatable { use HasFactory, Notifiable; /** * The attributes that are mass assignable. * * @var array */ protected $fillable = [ 'name', 'email', 'password', ]; /** * The attributes that should be hidden for arrays. * * @var array */ protected $hidden = [ 'password', 'remember_token', ]; /** * The attributes that should be cast to native types. * * @var array */ protected $casts = [ 'email_verified_at' => 'datetime', ]; // 下記を追記 /** * ユーザの電話番号を取得 * * @return void */ public function phone() { return $this->hasOne('App\Models\Phone'); } // 上記までを追記 }
-
アプリ名ディレクトリで下記コマンドを実行してtinkerを起動する。
$ php artisan tinker
-
tinkerで下記を実行してnull以外が帰ってくることを確認する。(usersテーブルとphonesテーブルにそれぞれデータが格納されているものとする。スペルミスがないのにnullが帰ってきてしまうときはtinkerを再起動する。)
use App\Models\User; User::find(1)->phone;
-
- phonesテーブルからusersテーブルに対するモデルファイルへの定義記載
-
アプリ名ディレクトリで下記コマンドを実行してUserモデルファイルを開く。
$ vi app/Models/Phone.php
-
下記のようにリレーションを定義する。
アプリ名ディレクトリ/app/Models/Phone.php<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Phone extends Model { use HasFactory; // 下記を追記 public function user() { return $this->belongsTo('App\Models\user'); } // 上記までを追記 }
-
アプリ名ディレクトリで下記コマンドを実行してtinkerを起動する。
$ php artisan tinker
-
tinkerで下記を実行してnull以外が帰ってくることを確認する。(usersテーブルとphonesテーブルにそれぞれデータが格納されているものとする。スペルミスがないのにnullが帰ってきてしまうときはtinkerを再起動する。)
use App\Models\Phone; User::find(1)->user;
-
超簡単なまとめ
- 1対1のリレーションはメインテーブル→サブテーブルのときはhasOne(サブテーブルに紐づくモデル名)を使用し、サブテーブル→メインテーブルのときはbelongsTo(メインテーブルに紐づくモデル名)と記載する。