Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

automica's avatar

Best practice for CRUD updating an existing belongsToMany in API

I'm working on adding CRUD endpoints to our API to allow the assignment of two models via a belongsToMany relationship.

We have Form and Item which are bound by a belongsToMany relationship.

I've created POST/ store endpoint allowing user to pass in single pair of [form_id, item_id]. With the id generated from that result, then we can hit an PUT/ UPDATE method which would allow [id, form_id, item_id] to be updated.

Being able to update this way seems a bit weird to me as I'd need to ensure we're not adding duplicate records. Does anyone has advice on whether its sensible to include that, or whether to change the store method to behave like sync?

eg

$form->items()->sync([1, 2, 3]);

Advice as always gratefully received.

0 likes
3 replies
martinbean's avatar
Level 80

@automica Most RESTful APIs I tend to loosely follow the JSON:API spec. They take the route of having a specific route for manipulating a parent resource’s relations. So if you have a form resource, then you could have a URL like /forms/{form}/relationships/items that attached/detaches/syncs related items for that form:

  • PATCH /forms/{form}/relationships/items would replace items with the items in the request (i.e. sync)
  • POST /forms/{form}/relationships/items would add requested items (i.e. attach)
  • DELETE /forms/{form}/relationships/items would remove requested items (i.e. detach)

More information: https://jsonapi.org/format/#crud-updating-to-many-relationships

2 likes
newbie360's avatar

be careful the ->sync() method would not change update_at of the exists record

if you want make sure all the update_at has same timestamp

$newCars = array_map('intval', array_values($request->validated()['cars']));
$oldCars = $user->cars->pluck('id')->toArray();

if ($newCars !== $oldCars) {
    // all the same updated_at here
    $user->cars()->detach();
    $user->cars()->attach($newCars);
}

Please or to participate in this conversation.