Laravelの更新画面で1つのテーブルデータに対して更新するだけであれば比較的簡単なのですが、主テーブルとその子(多)テーブルに対しても更新したい場合があります。
今回はLaravelでリレーションDBの1対多のデータに対して更新する方法をご紹介します。(Laravelバージョン6系)
多のデータは増減(更新画面にて入力追加・削除)有りのデータになります。
親子関係(1対多)の2つのテーブル構造
親子関係(1対多)の2つのテーブルを用意しました。
部署(departmentsテーブル)に所属する複数の社員(employeesテーブル)レコードが登録されてるテーブル構造です。
部署テーブル:departmentsテーブル(親)
名前 | 説明 |
---|---|
id | 主キー |
department_name | 部署名 |
所属社員テーブル:employeesテーブル(子)
名前 | 説明 |
---|---|
id | 主キー |
employee_name | 社員名 |
department_id | 部署ID=departmentsテーブルのid ※departmentsテーブルのテーブル名から「s」を除いた名前「department」とdepartmentsテーブルの主キー「id」にアンダーバー「_」を付けた名前「department_id」にする必要があります。こうすることでdepartmentsテーブルからidが一致したデータを取得することができます。 |
親と子のテーブルデータ用のModelを用意
※Departmentモデル、Employeeモデルを用意します。
departmentsテーブル(親)のテーブルデータ用Modelの記述
※Department.phpファイルを用意します。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Department extends Model
{
}
employeesテーブル(親)のテーブルデータ用Modelの記述
※Employee.phpファイルを用意します。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Employee extends Model
{
}
部署、所属社員の更新フォーム(更新ページ)のviewの記述
※departmentsedit.blade.phpファイルを用意します。1部署に最大5人の社員名まで更新できるフォームです。
@if (session('message'))
<div class="message">
{{ session('message') }}
</div>
@endif
@include('common.errors')
<form enctype="multipart/form-data" action="{{ url('departments/update') }}" method="POST">
@csrf
<div>
<label for="id">部署ID</label>
<div>{{$department->id}}</div>
<input type="hidden" name="id" value="{{$department->id}}">
</div>
<div>
<label for="department_name">部署名※</label>
<input type="text" id="department_name" name="department_name" value="{{ old('department_name') }}">
</div>
<ul>
<li>
<label>所属社員名1</label>
<input type="text" name="employee_name[]" value="{{ old('employee_name.0', $employees[0]->employee_name ?? '') }}">
</li>
<li>
<label>所属社員名2</label>
<input type="text" name="employee_name[]" value="{{ old('employee_name.1', $employees[1]->employee_name ?? '') }}">
</li>
<li>
<label>所属社員名3</label>
<input type="text" name="employee_name[]" value="{{ old('employee_name.2', $employees[2]->employee_name ?? '') }}">
</li>
<li>
<label>所属社員名4</label>
<input type="text" name="employee_name[]" value="{{ old('employee_name.3', $employees[3]->employee_name ?? '') }}">
</li>
<li>
<label>所属社員名5</label>
<input type="text" name="employee_name[]" value="{{ old('employee_name.4', $employees[4]->employee_name ?? '') }}">
</li>
</ul>
<button type="submit" class="btn-entry">更新</button>
</form>
Routeの記述
※ページURLは必要に応じて変更して下さい。
//更新画面
Route::post('/departmentsedit/{departments}','DepartmentsController@edit');
//更新処理
Route::post('/departments/update','DepartmentsController@update');
リレーションDBの1対多のデータに対して更新するControllerの記述
※(親)部署:departmentsテーブルデータ更新時に親テーブルのid(主キー)を使用しfor文とsave()を使って(子)所属社員:employeesテーブルにデータを更新(update)・登録(create)・削除(delete)する、DepartmentsController.phpファイルを用意します。
Department、Employeeモデルの読込
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use App\Department; //Departmentモデルを使用
use App\Employee; //Employeeモデルを使用
use Validator; //バリデーションを使用
use DB;
更新画面と更新処理のControllerの記述
※更新画面の表示「edit($id)~」と更新処理「update(Request $request)~」の記述です。
更新処理では入力後「//バリデーションチェック」を行い、「部署テーブル:departmentsテーブル(親)を更新」を行った後、入力された「//所属社員名1~5を配列で取得」します。「departmentsテーブル(親)のid(主キー)と一致する、所属社員テーブル:employeesテーブル(子)に登録されてる複数レコードを取得」し、for文内で「//所属社員テーブル:employeesテーブル(子)に登録されてる複数レコードの更新・登録・削除処理」を行います。
class DepartmentsController extends Controller{
//更新画面
public function edit($id)
{
$department = Department::find($id);
$employees = DB::select("SELECT * FROM employees WHERE department_id = ".$id."");
return view('departmentsedit', [
'department' => $department,
'employees' => $employees,
]);
}
//更新処理
public function update(Request $request) {
//バリデーションチェック
$validator = Validator::make($request->all(), [
'department_name' => 'required',
'department_name' => 'max:255',
]);
//バリデーション:エラー
if ($validator->fails()) {
return redirect('/departmentsedit')
->withInput()
->withErrors($validator);
}
//部署テーブル:departmentsテーブル(親)を更新
$departments = Department::find($request->id);
$departments->department_name = $request->department_name;
$departments->save();
//所属社員名1~5を配列で取得
$employee_names = $request->get('employee_name');
//departmentsテーブル(親)のid(主キー)
$department_id = $request->id;
//departmentsテーブル(親)のid(主キー)と一致する、所属社員テーブル:employeesテーブル(子)に登録されてる複数レコードを取得
$employees = Employee::where('department_id', $department_id)->get();
//所属社員テーブル:employeesテーブル(子)に登録されてる複数レコードの更新・登録・削除処理
for($i=0; $i<5; $i++){
//employeesテーブルに登録されてる複数レコード更新(update)
if($i < count($employees)){
//所属社員名が入力されている場合
if($employee_names[$i] != "" && !empty($employee_names[$i])){
$employees->employee_names = $employee_names[$i];
}else{
//employeesテーブルに登録されてる複数レコードより入力項目が少ない場合は削除(delete)
Employee::where('id', $employees[$i]->id)->delete();
}
}else{
if($employee_names[$i] != "" && !empty($employee_names[$i])){
//employeesテーブルに登録されてる複数レコードより入力項目が多い場合は登録(create)
$employee = New Employee;
$employee->department_id = $department_id; //departmentsテーブル(親)のid(主キー)を登録
$employee->employee_names = $employee_names[$i];
$employee->save();
}
}
}
return redirect('/departmentsedit')->with('message', 'データを更新しました');
}
}
※流用される場合は自己責任でお願いします。