@malhayek To be specific - there are no bulk actions in eloquent. No matter what, you can just cut the code, but real insert/update/whatever will not be bulk, but separate action for each single model/row.
That said, you can simply run array_map or foreach with updateOrCreate for each item in the loop.
@malhayek If we talk about eloquent, then certainly yes.
If you worry about performance of this action, then you can do it in 4 steps:
get the existing rows with single query and orWheres
reduce the array of values to update/insert to separate those arrays: one to be inserted and other created
run bulk insert DB::table('your_table')->insert($array_of_arrays_with_values)
build update query with case when ... then ... statement
This way you end up with 3 queries, but you need to take care of the logic above and also make sure to add proper fields to both point 3 and 4 (eg. timestamps, since eloquent will not be in action here)
So basically, upsert will update multiple records and insert new one if matching not found.
Notes: Number of column should be same in requested array including id with blank value to insert new records. Check the below example:
In the following array first record will be updated and second array will be inserted into the database:
array:2 [▼
0 => array:5 [▼
"id" => 23
"job_card_id" => 7
"name" => "Oil change"
"quantity" => 10
"price" => 20
]
1 => array:5 [▼
"id" => null
"job_card_id" => 7
"name" => "Test"
"quantity" => "5"
"price" => "10"
]
]
JobCardService::upsert(
$request->only('services'), // All fields
['id'], // Unique fields
['job_card_id', 'name', 'quantity', 'price'], // Update or Insert columns in db
);