Search code examples
ember.jsember-dataember-cliemberfire

How do you save a many-to-many relationship in Ember and Firebase


Let's say we have many medicines that can be prescribed to many patients. Our model would look like this:

App.Medicine = DS.Model.extend({
  name: DS.attr(),
  patients: DS.hasMany('user', { async: true }), 
});

App.User = DS.Model.extend({
  name: DS.attr(),
  medicines: DS.hasMany('medicine', { async: true })
});

In this scenario, how do we save records to a Firebase store?


Solution

  • App = Ember.Application.create();
    
    App.ApplicationAdapter = DS.FirebaseAdapter.extend({
      firebase: new Firebase('https://YOUR_FIREBASE.firebaseio.com/')
    });
    
    
    App.Router.map(function(){ });
    
    App.Medicine = DS.Model.extend({
      name: DS.attr(),
      patients: DS.hasMany('user', { async: true }), 
    });
    
    App.User = DS.Model.extend({
      name: DS.attr(),
      medicines: DS.hasMany('medicine', { async: true })
    });
    
    App.IndexRoute = Ember.Route.extend({
      model: function() {
        var medicines = this.store.find('medicine');
        var users = this.store.find('user');
        return {
          medicines: medicines,
          users: users
        };
      },
      actions: {
        savePost: function(){
          var store = this.store;
          var medicine1 = store.createRecord('medicine', {name: 'aspirin'});
          var patient1 = store.createRecord('user', {name: 'Jane'});
          var patient2 = store.createRecord('user', {name: 'Peter'});
          medicine1.save()
          .then(function(){
            return Ember.RSVP.Promise.all([
              patient1.save(),
              patient2.save()
            ])
           .then(function(){
              var promises = [];
              var patientsOfMedicine1 = medicine1.get('patients');
              var medicinesOfPatient1 = patient1.get('medicines');
              var medicinesOfPatient2 = patient2.get('medicines');
              promises.push(patientsOfMedicine1, medicinesOfPatient1, medicinesOfPatient2);
              return Ember.RSVP.Promise.all(promises);
            })
            .then(function(arrayOfAttachedArrays){
              var promises = [];
              var patientsOfMedicine1 = arrayOfAttachedArrays[0];
              var medicinesOfPatient1 = arrayOfAttachedArrays[1];
              var medicinesOfPatient2 = arrayOfAttachedArrays[2];
              patientsOfMedicine1.addObjects(patient1, patient2);
              medicinesOfPatient1.addObject(medicine1);
              medicinesOfPatient2.addObject(medicine1);
              promises.addObjects(medicine1.save(),patient1.save(),patient2.save());
              return Ember.RSVP.Promise.all(promises);
            });
    
          });
        }
      }
    });
    

    Notes:

    • Thanks to David Govea for showing me how this works.
    • If there's a better way to do this, please post below.