Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

remove child from hasMany relationship

How do you remove a child from a hasMany relationship without deleting the child?

I have tried setting the foreign_key of the child to null. I have also tried using removeObject on the parent relationship.

here is an example.

App.Invoice = DS.Model.extend
  lines: DS.hasMany('App.Line')

App.Line = DS.Model.extend
  invoice: DS.belongsTo('App.Invoice')

App.InvoiceController = Ember.Controller.extend
  removeLine: (line) ->
    @get('content.lines').removeObject(line)
    line.set('invoice', null)
    @get('store').commit()

App.InvoiceEditView = Ember.View.extend
  templateName: 'invoice'

App.LineView = Ember.View.extend
  tagName: 'tr'
  templateName: 'line'


#invoice template
<table>
    {{#each content.tasks}}
      {{view App.LineView}}
    {{/each}}
</table>

#line template
<td><a {{action "removeLine" view.context}}>remove</a></td>
<td>{{description}}</td>
<td>{{price}}</td>
<td>{{price}}</td>

I am currently using

jquery 1.8.2
ember.js v1.0.pre-4
ember-data v11
like image 913
Aaron Renoir Avatar asked Oct 05 '12 00:10

Aaron Renoir


2 Answers

In the remove() function, it commit()'s and then calls remove() again. That would cause the "setProperty in state rootState.loaded.updated.inFlight" error, because the record cannot be changed while the Ajax request is inflight.

If your intention is to actually delete the Line, thereby removing it from the hasMany association, then I suggest a remove() function like:

remove: function(event) {
  var item = event.context;
  if (item.get('isDeleted')) return;
  item.deleteRecord();
  App.store.commit();
  return item;
}

Note that once something has be marked for deletion by deleteRecord(), it will remain live in Ember with isDeleted == true until a commit() completes successfully. You may want to add a classNames binding to hide it with CSS once it's marked for deletion:

#line template
<tr {{bindAttr class="isDeleted"}}>
  <td><a {{action "removeLine" target="view"}}>remove</a></td>
  <td>{{description}}</td>
  <td>{{price}}</td>
  <td>{{price}}</td>
</tr>

With CSS like:

.is-deleted { display: none; }
like image 109
Mars Avatar answered Oct 22 '22 22:10

Mars


It seems that setting invoice to an empty string works.

 App.InvoiceController = Ember.Controller.extend
   removeLine: (line) ->
     @get('content.lines').removeObject(line)
     line.set('invoice', '')
     @get('store').commit()
like image 1
Aaron Renoir Avatar answered Oct 23 '22 00:10

Aaron Renoir