Saving parent & child to rails (at once?)


#1

Hi, I struggled through so many posts here and on stackoverflow without any luck.

App.ApplicationAdapter = DS.ActiveModelAdapter.extend()

I have a simple relationship between two models:

App.Order = DS.Model.extend(Ember.Validations.Mixin,
  transportationCosts: DS.attr("number")
  ...
  items: DS.hasMany("order-item")
)
App.OrderItem = DS.Model.extend(
  quantity: DS.attr("number")
  ...
  order: DS.belongsTo("order")
  item: DS.belongsTo("item")
)
App.Item = DS.Model.extend(
...

Now I fill up the order with orderItems like this.

  orderItem: (item) ->
    o = @content
    itemAlreadyInOrder = false
    o.get('items').forEach (oi) ->
      if oi.get('item') is item
       itemAlreadyInOrder = true
       oi.set 'quantity', io.get('quantity')+1
    if itemAlreadyInOrder is false
      oi = o.get('items').createRecord 'order-item'
      oi.set 'quantity', 1
      oi.set 'item', item

That works well. I think all relationships are looking good.

Now I want to save that order, including it’s orderItems to my Rails backend. First, how is this officially done with ember-data? By first saving the child to the server and then saving the parent? How would this be implemented on the rails side? Should it save the record and wait for the parent and regularly clean the db from incomplete records?

My idea was, that both the parent with it’s embedded children could be posted to the server in one POST, with embedded children. looking like

{
    "order": [
        {
            "transportationCosts": 20,
            "order-items": [
                {
                     "quantity": 2,
                     "item_id": 85
                }
            ],
        },
    ],
}

I know, this is not how records are embedded normally by ember. On order you would have a item_ids array and beside the order key in the root hash you would have a items key listing the items. Thats how I receive records from rails. But because the id’s are not yet known when posting this type of embedding doesn’t work. So how to do it? Do I have to write a specific serializer? Or stick with the official way, and which would this be?

Thank you very much for all your help!!


#2

What did you end up with? I’m wondering the same thing.


#3

rails expects the nested items to come in as order_items_attributes and will create them directly if you have accepts_nested_attributes_for order_items on your rails order model http://apidock.com/rails/ActiveRecord/NestedAttributes/ClassMethods/accepts_nested_attributes_for

create a specific serializer for your order model (serializers/order.js) and add this code or something similar (this is written in the ember-cli style)

import DS from 'ember-data';

export default DS.ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, {
      
attrs: {
  orderItems: {serialize: 'records', deserialize: 'ids'}
},

serialize: function(record, options) {
	var json = this._super(record, options);
	json.order_items_attributes = json.order_items;
	delete json.order_items;

       return json;
}
});