8

I know this subject has already been discussed around stackoverflow and other forums, but I cannot find the right way to do it.

I have a model called "post" which contain post information (user, description, etc...). The user receive a few post, reads them and make actions on them. The posts are coming from my api when I request a GET /api/posts/

I also have a model called "post-state" where I save the action of people reading the post: when they like, share, vote, or favourite the post.

export default DS.Model.extend({
    post: belongsTo('post'),
    user: belongsTo('user'),
    liked: attr('boolean', { defaultValue: false }),
    favourited: attr('boolean', { defaultValue: false }),
    voted: attr('boolean', { defaultValue: false }),
    shared: attr('boolean', { defaultValue: false }),
});

I'm looking for a way for my ember application to save my post-state models in a bulk, just the way I received the post in a bulk as well. The post states would be saved with an api call POST /api/post-states/

I've read in a discussion that the best way would be to create a custom adapter, but I'm not sure what to put in it to be able to do that... maybe to create a function saveAllRecords()?

What would be the best solution for me?

Thank you for you help!

alexmngn
  • 9,107
  • 19
  • 70
  • 130
  • 1
    Ever looked at this : http://emberjs.com/api/data/classes/DS.Store.html#method_pushPayload Or an array of records you can .invoke('save') [don't know if this it all with one single push. May have to override store.scheduleSave] – Hillboy Feb 10 '16 at 13:49
  • designing the POST request payload whether through ED models or via a custom request depends primarily on the back-end's capabilities whether it can atomically batch process interrelated models, etc. If not, still performing a request via a hash or array promise might work but again the results may vary depending on how the back-end would treat the requests. Possible solutions: https://www.emberjs.com/api/ember/3.7/modules/rsvp. This question bares some clarification. – ashraf Jan 13 '19 at 03:03

2 Answers2

3

I've looked around and it seems like there is no proper way to do this with Ember, but I've come up with something I'm not sure how much of the Ember Way it is. What you can do is make a different model that contains a hasMany attribute that would contain the models you want to bulk save, and then add those models to the container model and you can play with the serializer/adapter to get what you want. Here is how it would work:

Model (lets call it post-state-container)

import DS from 'ember-data';

export default DS.Model.extend({
  postStates: DS.hasMany('post-state')
});

Serializer

import DS from 'ember-data';
import Ember from 'ember';

export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
  attrs: {
    postStates: { embedded: 'always' },
  },
  serializeIntoHash: function(data, type, record, options) {
    Ember.$.extend(data, this.serialize(record, options));
  }
});

You can massage the payload sent to the server here to fit what you need for your backend, because you will get a list of serialized post-state objects in JSON format from this.serialize(record, options)

Adapter

import DS from 'ember-data';

export default DS.RESTAdapter.extend({
  namespace: 'api',
  urlForCreateRecord: function() {
    return this.get('namespace') + '/post-states';
  },
});

How to use it (probably and action in a route or controller somewhere)

  let record1 = this.store.createRecord('post-state'); //These would be your populated records
  let record2 = this.store.createRecord('post-state'); //These would be your populated records
  let postStateContainer = this.store.createRecord('post-state-container');
  postStateContainer.get('post-state-container').pushObject(record1);
  postStateContainer.get('post-state-container').pushObject(record2);
  postStateContainer.save();

I've tested this, and it works. I'm not sure if there is a better way using JSONApi or something like that

tabiodun
  • 83
  • 4
1

You could look how ember-api-actions does it. Check out the build-url and one of the files that contains the method to do the ajax call. You could basically copy the methods and use it in your model. But I think it would be easier to just use the addon at this point :)

Piotr
  • 860
  • 5
  • 11
  • I took a look into this addon and I'm not a huge fan of the way it was been built, it doesn't really respond to my need. – alexmngn Feb 07 '16 at 22:21