Saving a record and using "includes"?

Hi everyone, I need a little help with something.

I’m using EmberJS 3.5, Ember Data 3.7 and Ember CLI 3.7

I have a model with lots of relations (hasMany and belongsTo). The backend sends some of the relations included by default when I load the model using findRecord, but in the edit form I want to load them all so I load the model on my route model() hook with the following code:

model({ id }) {
   return this.store.findRecord('my-model-name', id, {
        include: 'relation1,relation2,relation3.......relationN' //really long chain of relations
   }
}

When I save the relation using an ember concurrency-task I just do:

let { model } = this;
yield model.save();

What happens is the backend saves the model, but then returns back the saved item with only the items that are usually included by default (and missing the ones that were included in the model() hook, which essentially “wipes” some of the values that were just been saved from the client (if I refresh the page without saving again, everything is there).

I would assume, I would want to do something like model.save({include: 'include-all-again'}) but that doesn’t seem to work (also tried with .save({adapterOptions: {include: 'include-all-again'}}))

Currently what I’m doing to overcome this is (reloading the model again after saving):

let { model } = this;
yield model.save();
yield this.store.findRecord('my-model-name', model.id, { include: 'include-all-relations' });

This doesn’t seem what I would want, anyone can point in me the right direction of this?

2 Likes

The same issue here, after 3 years. Nobody interested?

Can you describe your situation in a little detail? I’m not totally sure what the OP was expecting vs seeing but it feels like it was either a backend issue or a misunderstanding of how the “include” thing works…

@corrspt @Mehran_Naghizadeh :wave: .

You should be able to customize the urlForUpdateRecord in the adapter. Like this:

import JSONAPIAdapter from '@ember-data/adapter/json-api';

export default class MyModelAdapter extends JSONAPIAdapter {
  urlForUpdateRecord(id, modelName, snapshot) {
    return super.urlForUpdateRecord(...arguments) + '?include=relation1,relation2,relation3';
  }
}
1 Like

Hey @esbanarango , that’s actually a very nice solution, thanks for sharing :slight_smile:

I’m still using the save+reload after save trick after all this time :slight_smile: I’ll need to try yours :slight_smile:

@dknutsen I have a model with a bunch of related data, the backend doesn’t return all possible included data when we just load the model using findRecord , in order to get all data you need to include the relations you want (normal JSON:API stuff)

If I save the model, the response for the backend just returns the normal data without the included part. As such, from the customer perspective, will ‘empty fields that had a value before’ after it finished saving. Either the backend when saving returned always all data (which sometimes is not really necessary, as you may want to just update something small) or I would need a way to include that information in the save request.

Either way, at the time I didn’t know how to twist my backend library to do such a thing :stuck_out_tongue: hence the question.

This sounds exactly like what I would expect… when you save a model you’re only updating one record, so that’s all the API would typically return. The ?include bit is just a way to more efficiently sideload data when you’re querying it, IIRC not really as relevant for a save operation. A PUT/PATCH shouldn’t change the associated records unless A. your request is telling it to, B. your backend is returning something weird for the relationships (e.g. it’s clearing them every time). How does your API serialize relationships? Ids? Links?

from the customer perspective, will ‘empty fields that had a value before’ after it finished saving

This is the part that doesn’t sound right. The frontend should still have a cache of the resolved relationships, so unless Ember is being “told” to clear the relationships by the backend it shouldn’t do that. Hence my above questions about how your API is serializing the relationships (if at all). What does your API response to a PUT/PATCH look like?

EDIT: I guess it’s worth stating explicitly that ?include is not a way of telling the client what records are related to what records, it’s just a convenient way to load said relationships in a single request. There should still be another reference (either ids or links) for introducing your related data.