Laravelの1対多リレーションとは何かと記述方法のまとめ
1011 回閲覧されました
みなさんこんにちは、jonioです。
前回はLaravelの1対1リレーションが何かと記述方法について解説しました。
リレーションが何か分からない方はまず↓を読んだ方がいいです。
今回は1対多リレーションと記述方法についてのまとめです。
目次
1対多リレーションとは
まずはざっくりと1対1リレーションを例でおさらいします。
リレーションはテーブル同士を繋ぐ時に使用します。
例えばuser(人)テーブルとemail(メール)テーブルがあったとして1人が1つのメールを持つのが普通なので人とメールは1対1の関係になります。
何か1つに別の何か1つが対応するのが1対1リレーションです。
何となく分かるかもしれませんが何か1つに別の何か複数が対応するのが1対多リレーションです。
具体例で見ていきましょう。
1対多リレーションの例
ある会社の部署があってそこには複数の従業員がいます。
この場合1つの部署に複数の従業員が対応します。
こんな場合に部署テーブル(departmentsとします)と従業員テーブル(employeesとします)を結び付けてdepartmentsテーブルからemployeesテーブルの情報を引っ張ってきたりemployeesテーブルからdepartmentsテーブルの情報を引っ張って来る時に1対多リレーションを使う事になります。
また部署に従業員が所属するので親に当たるテーブルがdepartmentsで子に当たるテーブルがemployeesです。
まずは下準備です。
下準備
リレーションの記述をする前に子テーブルにリレーションに必要なカラムを作成しないといけません。
departmentsテーブルとemployeesテーブルを作成して↓とします。
↓で子テーブルのemployeesテーブルのカラムにdepartment_idがあるのが確認できますが1対1リレーション・1対多リレーションのどちらでも子テーブルのカラムに「親テーブルのモデル名_id」を作成しないといけません。(親テーブルのモデル名はdepartmentです)
次は使用するテーブルの中身です。
使用するテーブルの中身
今回使用するテーブルは以下とします。
↓はdepartmentsテーブルです。
↓はemployeesテーブルです。
親テーブルのidカラムの事を主キー・子テーブルのdepartment_idカラムの事を外部キーと呼んでいて主キーと外部キーの値が紐づきます。
departmentsテーブルのidが1に対してemployeesテーブルのdepartment_idの1が紐づいています。
図にすると↓です。
同じ数字が紐づくと覚えましょう。
それではコードを書いていきます。
親テーブルから子テーブルの情報を引っ張る
親テーブルのモデル(Department.php)に↓の記述をします。
親テーブルから子テーブルの情報を引っ張って来る事ができる様にする時は親モデルにメソッドを書きます。
そのメソッドが7行目のemployeesでemployeeを複数形にしています。
親のモデルで書くメソッド名は子モデル名にsを付けて書きます。(そうしないといけない訳ではなく一般的にそうするみたいです)
8行目の「return $this->hasMany(Employee::class);」ですがEmployeeは子モデル名を書きます。
それ以外はそのままでいいです。
これで親テーブルから子テーブルの情報を使う事ができる様になりました。
子テーブルの情報を表示
ルーティングの設定をしてコントローラーは↓の記述をします。
1行目ですがモデルを使用して子テーブルの情報を使う事ができる為の設定をしています。
11行目の「Department::find(2)->employee->name;」がリレーションを使って親テーブルから子テーブルの情報を引っ張っています。
「Department::find(2)」がdeparatmentsテーブルのidカラムの値が2を選択して「employee」がemployeesテーブルですが「Department::find(2)->employee」がdepartmentsテーブルのidカラムの値が2に対応するemployeesテーブルという意味です。
「name」がemployeesテーブルのnameカラムです。
よって「Department::find(2)->employee->name」はdepartmentテーブルのidカラムの値が2に対応するemployeesテーブルのdepartment_idの値が2のnameカラムの値、つまり「れい」という事になります。
次は子テーブルから親テーブルの情報を引っ張ります。
子テーブルから親テーブルの情報を引っ張る
子テーブルのモデル(Employee.php)に↓の記述をします。
親テーブルから子テーブルの情報を引っ張って来る時と記述はほぼ同じですが7行目のメソッド名には「s」を付けません。
また8行目ですが「hasMany」の部分が「belongsTo」に変わります。
親テーブルの情報を表示
ルーティングを設定してコントローラーは↓の記述をします。
子テーブルの情報を表示する時と全く同じです。
employeesテーブルのdepartment_idの値が1に対応するdepartmentsテーブルのidカラムが1のnameカラムの値なので「human resources」になります。