laravel-json-api / laravel

JSON:API for Laravel applications

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Issue] On Store attaching Morph To Many only creates one of the resources

DellanX opened this issue · comments

I'm running into an issue where if I create a resource with multiple relationships attached via a polymorphic pivot table, then only one of the models are attached. Furthermore, it looks like the ID increments oddly, leading me to suspect that the controller is detaching attributes (updating all related as if a PATCH request).

Context

I have an odd data structure where there are groups, users, and polymorphic pivot table "membership."
(MorphedToMany/MorphedByMany, the inverted scenario of polymorphic-to-many)

user: {
  id: number,
  name: string,
}

group: {
  id: number,
  name: string,
}

membership: {
  id: number,
  user_id: number,
  shared_resource_type: string,
  shared_resource_id: number,
  membership: "member"|"owner",
}

Groups have the following in the schema

BelongsToMany::make('members')->type('users'),
BelongsToMany::make('owners')->type('users')->fields(static fn ($parent, $related) => [
    'membership' => 'owner',
]),

Groups have the following in the request

'members' => JsonApiRule::toMany(),
'owners' => JsonApiRule::toMany(),

The Issue

Here is where things get odd, if I send the following in a POST request:

{
  "data": {
    "type": "groups",
    "attributes": {
      "name": "Membership Test"
    },
    "relationships": {
      "members": {
        "data": [
          {
            "type": "users",
            "id": "3"
          }
        ]
      },
      "owners": {
        "data": [
          {
            "type": "users",
            "id": "2"
          }
        ]
      }
    }
  }
}

Then then the following will happen in the database:

  1. Only the ownership will be created.
  2. The ownership ID has skipped a number. (Went from 55 to 57, no 56 exists)

My hypothesis

I think what is happening here is that instead of adding a member and an owner, the controller is:

  1. Updating the membership relationship to match the request
  2. Updating the ownership relationship to match the request, which detaches all members in the process.