Data: Empty hasMany relationship not sent to server by model.save()

Created on 24 Jul 2018  路  15Comments  路  Source: emberjs/data

While QAing our next release and we had to downgrade ember-data to 3.1.1 from 3.2.0 because of a weird bug.

When updating a hasMany relationship to an empty array and called .save() on the owning model, the empty array is not sent to the server.

example:

const Child = Model.extend({
   parent: belongsTo('parent', { async: false })
})

const Parent = Model.extend({
   items: hasMany('child', {async: false})
})

... later ...

const model = store.findRecord('parent', 99);
model.get('items').mapBy('id'); // ['1', '2', '3']

model.set('items', A());
model.save();

In 3.1.1, this worked --- an empty relationship would be sent to the server.

After upgrading to 3.2.0, it not longer sends the empty relationship.

Unfortunately, I haven't been able to put together a simple repo recipe on github - I only have the rather complicated example that is our application (which I can't share for obvious reasons).

I have to leave the office right now but will try to get some more details in this issue when I can (probably tomorrow).

That said, please be careful upgrading to 3.2.0 :)

Most helpful comment

@ryanto @runspired I looked at the commits and could only find that fix in v3.4.0-beta.1
Might be a good idea to release a v3.3.1 with that fix, alongside #5541

All 15 comments

@ryanto did your work land prior to 3.2 or is this related to it?

@runspired @ryanto I suspect that [this line] is to blame. you can see it in the [diff from 3.1.1 to 3.2.0].

```
// only serialize has many relationships that are not new
let nonNewHasMany = hasMany.filter(item => item.record && !item.record.get('isNew'));

    if (nonNewHasMany.length > 0) { // <---- BUG HERE -- this line was added
      json.relationships = json.relationships || {};
         ...
        json.relationships[payloadKey] = { data }; // <---- when the hasMany relationship is empty, an item is never added here
      }
    }

```

To fix it, we could add logic for the case where the relationship is completely empty and then add an empty data: [] item to the relationships hash.

Aside

While looking at the code, I also observe that isNew items are not serialized. Seems like we should warn the user that the relationships aren't going to be persisted because they are isNew, or even throw a fatal error while in dev mode.

@ryanto @runspired Let me know if you'd like me to get a PR up - I'd love to contribute.

Edit: Opps, I think I wasn't understanding this.

@les2 does this PR fix the issue? https://github.com/emberjs/data/pull/5466

If not, do you mind adding a failing test? There's a few example has many tests you can copy from in the jsonapi serializer

@runspired I think my fix was post 3.2

@ryanto @runspired I looked at the commits and could only find that fix in v3.4.0-beta.1
Might be a good idea to release a v3.3.1 with that fix, alongside #5541

3.3.1 was just released but this is still not fixed, you have to use 3.4.0-beta.2

@urbany 3.3 was a re-release of 3.2. They are and will effectively remain the same release.

(That's not to say we might not backport this, just why this was done post 3.2 and yet not in 3.3)

Here are the PRs merging the fix back into...

3.2: https://github.com/emberjs/data/pull/5546

3.3: https://github.com/emberjs/data/pull/5547

seems like 3.4 is also impacted. I have the same issue, and emberdata is clearly not serializing empty hasmany.

Hi @olivierchatry,

Have you enabled serializing the hasMany relationship in your serializer?

export default ApplicationSerializer.extend(, {
  attrs: {
    hasManyRelationshipNameHere: { serialize: true }
  }
});

Hello @ryanto !

I think it does serialize it, but as soon as there is not more element in the relationships, it does not serialized the relationships anymore, even if there was one before. So the partial update, on the server side, does not remove the last element.

edit: removed last comment, was looking as the wrong pane of the network debugger :)

Haaa wait, my fault, I override a function in my app that was producing the bug. Sorry !

Thanks @runspired !

Looks like the fix was released in 3.1.2 and 3.3.2. If you're running into this, give those versions a try.

@ryanto 3.1.2 seems to work, but I still have the same issue in 3.3.2. @runspired can you confirm what the situation is with back-porting a fix to 3.3.x ? If it helps, I can confirm that the issue is fixed in v3.4.2

Seems like I am having this issue in v3.4.4 (but not systematically on all models)...

Was this page helpful?
0 / 5 - 0 ratings