Reputation: 457
I have two mysql tables
1. sales (id,buyer_id)
2. sales_items (id,sales_id,item_id,price,quantity)
very simple two tables. I am having issue while want to update any record, like when I edit some sales record I can
Now I want to update sales_items tables also.
What I am doing now is
- first deleting all records of sales in sales_items table
- Add new records
$task = Auth::user()->sales_items()->where(['sales_id'=>1]);
$task->delete();
//$SalesProducts array have all rows
SaleItem::insert($SalesProducts);
code is working but is this correct approach or there is batter way to do that? I am using Laravel 8 Eloquent and all tables have models
Thanks
Upvotes: 2
Views: 2116
Reputation: 64466
Normally this type of update process is a bit lengthy but efficient and optimal as compared to delete and insert hack, there are many benefits of this approach
update_at
timestamp which will change on every update while in case of delete/insert the created_at
and updated_at
will have same values foreverLets say in database you already have 2 rows for sale 1
______________________________________________
| id | sales_id | item_id | price | quantity |
----------------------------------------------
| 1 | 1 | 1 | 20 | 5 |
----------------------------------------------
| 2 | 1 | 2 | 10 | 5 |
----------------------------------------------
Let say you have following collection to perform update for sale 1
$collection = collect([
[
"id"=> null,
"sales_id"=>1,
"item_id"=> 1,
"price"=>10,
"quantity"=> 0
],
[
"id"=> 1,
"sales_id"=>1,
"item_id"=> 1,
"price"=>10,
"quantity"=> 0
]
]);
Now if we compare database results and the requested update collection we can see the there is
To perform above updates first we need to collect all items where id is null so we will add these records in database
$addItems = $collection->whereNull('id');
if($addItems->count() > 0){
SaleItem::insert($addItems);
}
For update we need to collect items where id is present and these records will be updated in database as
$updateItems = $collection->whereNotNull('id');
foreach($updateItems as $key => $updateItem) {
SaleItem::where('id', $updateItem->id)->update($updateItem);
}
Or we can use upserts for first and second step as
SaleItem::upsert($updateItems, ['id']);
For delete we can get all ids from collection and perform delete operation on rows that do not match these ids as
$deleteItems = $updateItems->pluck('id');
SaleItem::whereNotIn('id', $deleteItems)->delete();
Upvotes: 1
Reputation: 15786
# Sale model
protected static function booted()
{
static::deleting(function ($sale) {
SaleItems::where('sales_id', $sale->id)->delete();
return true;
});
}
# Item model
protected static function booted()
{
static::deleting(function ($item) {
SaleItems::where('item_id', $item->id)->delete();
return true;
});
}
This should run whenever a Sale or Item fire the deleting event. I'm not sure if mass-deletion works correctly.
# sales_items table migration
$table->foreignId('item_id')
->constrained('items')
->onUpdate('cascade')
->onDelete('cascade');
$table->foreignId('sales_id')
->constrained('sales')
->onUpdate('cascade')
->onDelete('cascade');
This should delete automatically the sales_items record if they are associated with an item or sales that just got deleted. However, this will NOT work with softDeletes.
Upvotes: 0