In Laravel’s update screen, updating a single table is relatively simple, but sometimes you also need to update its child (many) table at the same time.
This article explains how to update one-to-many relational DB data in Laravel. (Laravel version 6)
The “many” data can be increased or decreased (added/removed on the update screen).
Two Table Structures with Parent-Child (One-to-Many) Relationship
We prepared two tables with a one-to-many parent-child relationship.
This structure registers several employee records (employees table) that belong to departments (departments table).
Department Table: departments (Parent)
| Name | Description |
|---|---|
| id | Primary Key |
| department_name | Department Name |
Employee Table: employees (Child)
| Name | Description |
|---|---|
| id | Primary Key |
| employee_name | Employee Name |
| department_id | Department ID = id of departments table ※The name must be “department_id,” which is created by removing the “s” from the departments table name (“department”) and adding an underscore “_” followed by the primary key name “id.” This allows retrieving data from the departments table where the id matches. |
Prepare Models for Parent and Child Table Data
※Prepare Department model and Employee model.
Model for departments table (Parent)
※Prepare Department.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Department extends Model
{
}
Model for employees table (Child)
※Prepare Employee.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Employee extends Model
{
}
Form View for Updating Department and Employees (Update Page)
※Prepare departmentsedit.blade.php.
This form allows updating up to 5 employees per department.
@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">Department ID</label>
<div>{{$department->id}}</div>
<input type="hidden" name="id" value="{{$department->id}}">
</div>
<div>
<label for="department_name">Department Name※</label>
<input type="text" id="department_name" name="department_name" value="{{ old('department_name') }}">
</div>
<ul>
<li>
<label>Employee Name 1</label>
<input type="text" name="employee_name[]" value="{{ old('employee_name.0', $employees[0]->employee_name ?? '') }}">
</li>
<li>
<label>Employee Name 2</label>
<input type="text" name="employee_name[]" value="{{ old('employee_name.1', $employees[1]->employee_name ?? '') }}">
</li>
<li>
<label>Employee Name 3</label>
<input type="text" name="employee_name[]" value="{{ old('employee_name.2', $employees[2]->employee_name ?? '') }}">
</li>
<li>
<label>Employee Name 4</label>
<input type="text" name="employee_name[]" value="{{ old('employee_name.3', $employees[3]->employee_name ?? '') }}">
</li>
<li>
<label>Employee Name 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">Update</button>
</form>
Route Definition
※Modify page URL as needed.
//Update screen
Route::post('/departmentsedit/{departments}','DepartmentsController@edit');
//Update processing
Route::post('/departments/update','DepartmentsController@update');
Controller for Updating One-to-Many Relational DB Data
※Prepare DepartmentsController.php, which performs update, create, and delete operations on the employees table (child) using the parent table’s id (primary key).
Import Department and Employee Models
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use App\Department; //Use Department model
use App\Employee; //Use Employee model
use Validator; //Use validation
use DB;
Controller Code for Update Screen and Update Processing
※This is the update screen display “edit($id)” and the update processing “update(Request $request).”
After validation, the department table (parent) is updated. Then employee names 1–5 are obtained as an array, and employees linked to the department_id are retrieved. Inside the for loop, the employees table (child) records are updated, created, or deleted.
class DepartmentsController extends Controller{
//Update screen
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,
]);
}
//Update processing
public function update(Request $request) {
//Validation check
$validator = Validator::make($request->all(), [
'department_name' => 'required',
'department_name' => 'max:255',
]);
//Validation error
if ($validator->fails()) {
return redirect('/departmentsedit')
->withInput()
->withErrors($validator);
}
//Update departments table (parent)
$departments = Department::find($request->id);
$departments->department_name = $request->department_name;
$departments->save();
//Get employee names 1–5 as array
$employee_names = $request->get('employee_name');
//Parent table departments' id (primary key)
$department_id = $request->id;
//Get employees linked to the department_id
$employees = Employee::where('department_id', $department_id)->get();
//Update / Create / Delete rows in employees table (child)
for($i=0; $i<5; $i++){
//Update existing employee record
if($i < count($employees)){
if($employee_names[$i] != "" && !empty($employee_names[$i])){
$employees->employee_names = $employee_names[$i];
}else{
//If fewer inputs than existing records → delete
Employee::where('id', $employees[$i]->id)->delete();
}
}else{
if($employee_names[$i] != "" && !empty($employee_names[$i])){
//If more inputs than existing records → create
$employee = New Employee;
$employee->department_id = $department_id; //Register parent ID
$employee->employee_names = $employee_names[$i];
$employee->save();
}
}
}
return redirect('/departmentsedit')->with('message', 'Data updated successfully');
}
}
※Use at your own risk.