I have a controller function to send multiple devices for repair (essentially an update request against multiple existing devices_repairs records). When I try to retrieve the devices from the devices table alongside the repair details (Devices table, devices_repairs table), the records are retrieved but when I try to update the values the update request doesn’t save the new data.
This is my controller function:
<?php public function sendMultiDevicesForRepair(sendDeviceForRepairRequest $request) { $request->validated(); $device_barcodes = ["BSC0626", "BSC0376"]; $devices = Devices::with('repairDetails')->whereIn('barcode',$device_barcodes)->get(); DB::transaction(function () use (&$devices) { foreach($devices as $device) { $device->repairDetails->repair_date_sent_for = request('repair_date_sent_for'); $device->repairDetails->job_number = request('jobNumber'.$device->barcode); $device->repairDetails->operator_date_sent = Carbon::now()->toDateTimeString(); $device->repairDetails->operator_sent_by = getCreatedUpdatedBy(); } }); $devices->push(); // perform a redirect if the transaction is successful return redirect('/devices/repair') ->with('success', 'The devices: ' . request('deviceBarcodes') . ' have been sent for repair.'); } ?>
When I do (dd($devices)) after changing the repair details in the loop, the attributes array has the new values, but again push() will not update the database even though no error is returned:
IlluminateDatabaseEloquentCollection {#1439 ▼ #items: array:2 [▼ 0 => AppDevices {#1446 ▼ +timestamps: false #table: "devices" #primaryKey: "device_id" #relations: array:1 [▼ "repairDetails" => AppDevicesRepairs {#1451 ▼ #table: "devices_repairs" #primaryKey: "device_id" #attributes: array:15 [▼ "device_id" => "54" "repair_damaged_by" => "157" "repair_damage_type" => "Screen Damage" "repair_date_received" => "2020-02-26" "repair_date_sent_for" => "2022-03-31" "repair_damage_notes" => "Cracked Screen - due to age not worth repairing" "repairer_name" => null "repair_is_user_damage" => "1" "job_number" => "1000.5312.9745" "operator_date_received" => "2020-02-26 00:00:00" "operator_received_by" => "56" "operator_date_sent" => "2022-03-31 16:30:11" "operator_sent_by" => "41" "photo_id" => null "photo_id_back" => null ] #original: array:15 [▼ "device_id" => "54" "repair_damaged_by" => "157" "repair_damage_type" => "Screen Damage" "repair_date_received" => "2020-02-26" "repair_date_sent_for" => null "repair_damage_notes" => "Cracked Screen - due to age not worth repairing" "repairer_name" => null "repair_is_user_damage" => "1" "job_number" => null "operator_date_received" => "2020-02-26 00:00:00" "operator_received_by" => "56" "operator_date_sent" => null "operator_sent_by" => null "photo_id" => null "photo_id_back" => null ] #changes: []
Here are my models. Devices Model:
class Devices extends Model { /** * @var bool $timestamps Disable timestamps */ public $timestamps = false; /** * @var string $table Name of the db table */ protected $table = 'devices'; /** * @var string $primaryKey Name of the primary key */ protected $primaryKey = 'device_id'; /** * @var array $fillable The attributes that are mass assignable. */ protected $fillable = [ 'status', 'order_reference', 'model', 'serial', 'imei', 'barcode', 'mobile_number', 'helpdesk_url_id', 'device_notes' ]; use Searchable; function repairDetails() { return $this->hasOne(DevicesRepairs::class, 'device_id'); } }
DevicesRepairs model:
<?php namespace App; use IlluminateDatabaseEloquentFactoriesHasFactory; use IlluminateDatabaseEloquentModel; class DevicesRepairs extends Model { use HasFactory; protected $table = 'devices_repairs'; protected $primaryKey = 'device_id'; public $timestamps = false; function device() { return $this->hasOne(Devices::class, 'device_id'); } }
What am I doing wrong? I had this working with separate DB::Table update queries but I much prefer to use eloquent.
Advertisement
Answer
you need to push data inside your foreach
loop
Instead of
DB::transaction(function () use (&$devices) { foreach($devices as $device) { $device->repairDetails->repair_date_sent_for = request('repair_date_sent_for'); $device->repairDetails->job_number = request('jobNumber'.$device->barcode); $device->repairDetails->operator_date_sent = Carbon::now()->toDateTimeString(); $device->repairDetails->operator_sent_by = getCreatedUpdatedBy(); } }); $devices->push();
Use this
DB::transaction(function () use (&$devices) { foreach($devices as $device) { $device->repairDetails->repair_date_sent_for = request('repair_date_sent_for'); $device->repairDetails->job_number = request('jobNumber'.$device->barcode); $device->repairDetails->operator_date_sent = Carbon::now()->toDateTimeString(); $device->repairDetails->operator_sent_by = getCreatedUpdatedBy(); $device->push(); // save data here } });