I have a User model which has a hasMany relationship to a Brands model and I am having issues updating the Brands for a user properly.
I have a form which allows a user to enter / delete / update their own Brands in text fields, the current method i am using to update the users Brands after they have entered them all or edited them is to delete all existing Brands associated with the User then loop over the values, create the Brand model and then ‘saveMany’ … But i seem to be getting a constraint violation when adding … I am wondering if there is a better way to do this;
My User
model has the following;
public function brands()
{
return $this->hasMany('Brands::class');
}
Then in my controller I have the following code to update the Brands;
$user->brands()->delete();
foreach ($request['brands'] as $brand) {
$brandArray[] = new Brand([
'name' => $brand['name'],
'rating' => $brand['rating'],
]);
}
!empty($brandArray) && $user->brands()->saveMany($brandArray);
Is there a better way of doing this?
4
Answers
It looks fine to me. But from my point of view,
Instead of deleting all fields, then creating them. You can use
updateOrCreate
eloquent method inside yourforeach
.And in place of
foreach
, you can use themap
method.Since you only want to delete all the previous brands of the user, and create brand new brands without editing anything, you can simply follow the concept below:
In your controller:
You can find more examples in laravel documentation on createMany method: https://laravel.com/docs/9.x/eloquent-relationships#the-create-method
You can also go a step further and validate the array from the request:
Hope this helps, good luck!
When you save everything you have for the user, do this under:
Let’s separate things into three parts:
# constraint key violation:
If you’ve added foreign key constraint on another table, and you need to delete the brands, you should also delete all those related data constrained by your foreign key.
# design
If deleting brand related data is not possible, then maybe we can think about if there is a better design. Maybe we could add a hook on the frontend that call a DELETE API whenever certain data is removed by the user.
# query
If the brand has some unique key, you could use
upsert
instead of saveMany. That will be more efficient.# conclusion
I would suggest deleting brands by hooks on the frontend whenever a brand is removed by users, and use
upsert
to deal withcreate and update
stuff