From 4dbfcfa98b836ecb919bc9f3ba5b18c6dab36098 Mon Sep 17 00:00:00 2001
From: Matthew Dillon <matthewrdillon@gmail.com>
Date: Mon, 4 Dec 2017 05:32:39 -0700
Subject: [PATCH] ENH: Refactor hasMany relations (#59)

Fixes #52
---
 app/components/collection/create-container.js | 70 ++++++-------------
 app/controllers/collections/create.js         |  2 +
 app/controllers/collections/detail/edit.js    |  2 +
 app/templates/collections/create.hbs          |  1 +
 app/templates/collections/detail/edit.hbs     |  1 +
 .../collection/create-container.hbs           |  8 +--
 6 files changed, 31 insertions(+), 53 deletions(-)

diff --git a/app/components/collection/create-container.js b/app/components/collection/create-container.js
index 0f5ab1c..ade79e2 100644
--- a/app/components/collection/create-container.js
+++ b/app/components/collection/create-container.js
@@ -11,6 +11,7 @@ export default Component.extend({
     this._super(...arguments);
     const model = this.get('model');
     const validations = this.get('validations');
+    const hasMany = this.get('hasMany');
 
     let changesets = {};
     changesets['new'] = [];
@@ -20,72 +21,43 @@ export default Component.extend({
                                         lookupValidator(validations['collection']),
                                         validations['collection']);
 
-    let collectionSpeciesChangesets = [];
-    const collectionSpecies = model.get('collectionSpecies');
-    collectionSpecies.forEach((cs) => {
-      const changeset = new Changeset(cs,
-                                      lookupValidator(validations['collectionSpecies']),
-                                      validations['collectionSpecies']);
-      collectionSpeciesChangesets.push({ model: cs, changeset: changeset });
+    hasMany.forEach((hasMany) => {
+      let relatedChangesets = [];
+      let validation = validations[hasMany];
+      const related = model.get(hasMany);
+      related.forEach((r) => {
+        const changeset = new Changeset(r, lookupValidator(validation),
+                                        validation);
+        relatedChangesets.push({ model: r, changeset: changeset });
+      });
+      changesets['hasMany'][hasMany] = relatedChangesets;
     });
-    changesets['hasMany']['collectionSpecies'] = collectionSpeciesChangesets;
-
-    let datasheetsChangesets = [];
-    const datasheets = model.get('datasheets');
-    datasheets.forEach((d) => {
-      const changeset = new Changeset(d,
-                                      lookupValidator(validations['datasheet']),
-                                      validations['datasheet']);
-      datasheetsChangesets.push({ model: d, changeset: changeset });
-    });
-    changesets['hasMany']['datasheets'] = datasheetsChangesets;
 
     this.set('changesets', changesets);
   },
 
   actions: {
-    addCollectionSpecies() {
+    addHasMany(modelName, relatedName) {
       const store = this.get('store');
       let changesets = this.get('changesets');
       const validations = this.get('validations');
-      const collection = this.get('model');
-      const cs = store.createRecord('collection-species', { collection: collection });
-      collection.get('collectionSpecies').pushObject(cs);
-      changesets['new'].pushObject(cs);
-      const changeset = new Changeset(cs,
-                                      lookupValidator(validations['collectionSpecies']),
-                                      validations['collectionSpecies']);
-      changesets['hasMany']['collectionSpecies'].pushObject({ model: cs, changeset: changeset });
+      const validation = validations[relatedName];
+      const model = this.get('model');
+      const related = store.createRecord(modelName, { collection: model });
+      model.get(relatedName).pushObject(related);
+      changesets['new'].pushObject(related);
+      const changeset = new Changeset(related, lookupValidator(validation), validation);
+      changesets['hasMany'][relatedName].pushObject({ model: related, changeset: changeset });
     },
 
-    deleteCollectionSpecies(changesetRecord) {
+    deleteHasMany(changesetRecord, relatedName) {
       let changesets = this.get('changesets');
       changesets['delete'].pushObject(changesetRecord.model);
-      changesets['hasMany']['collectionSpecies'].removeObject(changesetRecord);
+      changesets['hasMany'][relatedName].removeObject(changesetRecord);
     },
 
     updateDatasheet(changeset, event) {
       changeset.set('datasheet', event.target.files[0]);
     },
-
-    addDatasheet() {
-      const store = this.get('store');
-      let changesets = this.get('changesets');
-      const validations = this.get('validations');
-      const collection = this.get('model');
-      const d = store.createRecord('datasheet-attachment', { collection: collection });
-      collection.get('datasheets').pushObject(d);
-      changesets['new'].pushObject(d);
-      const changeset = new Changeset(d,
-                                      lookupValidator(validations['datasheets']),
-                                      validations['datasheets']);
-      changesets['hasMany']['datasheets'].pushObject({ model: d, changeset: changeset });
-    },
-
-    deleteDatasheet(changesetRecord) {
-      let changesets = this.get('changesets');
-      changesets['delete'].pushObject(changesetRecord.model);
-      changesets['hasMany']['datasheets'].removeObject(changesetRecord);
-    },
   },
 });
diff --git a/app/controllers/collections/create.js b/app/controllers/collections/create.js
index 37192de..8b27025 100644
--- a/app/controllers/collections/create.js
+++ b/app/controllers/collections/create.js
@@ -11,6 +11,8 @@ export default Controller.extend(ValidationMixin, {
   CollectionSpeciesValidations,
   DatasheetValidations,
 
+  hasMany: ['collectionSpecies', 'datasheets'],
+
   options: computed('projectOptions', 'studyLocationOptions',
                     'collectionTypeOptions', 'collectionMethodOptions',
                     'speciesOptions', 'adfgPermitOptions', function() {
diff --git a/app/controllers/collections/detail/edit.js b/app/controllers/collections/detail/edit.js
index 72c586c..205a4aa 100644
--- a/app/controllers/collections/detail/edit.js
+++ b/app/controllers/collections/detail/edit.js
@@ -11,6 +11,8 @@ export default Controller.extend(ValidationMixin, {
   CollectionSpeciesValidations,
   DatasheetValidations,
 
+  hasMany: ['collectionSpecies', 'datasheets'],
+
   options: computed('projectOptions', 'studyLocationOptions',
                     'collectionTypeOptions', 'collectionMethodOptions',
                     'speciesOptions', 'adfgPermitOptions', function() {
diff --git a/app/templates/collections/create.hbs b/app/templates/collections/create.hbs
index 7705ee7..ae0f2b0 100644
--- a/app/templates/collections/create.hbs
+++ b/app/templates/collections/create.hbs
@@ -6,6 +6,7 @@
     collectionSpecies=CollectionSpeciesValidations
     datasheet=DatasheetValidations)
   options=options
+  hasMany=hasMany
   onSave=(action 'onSave')
   onCancel=(action 'onCancel')
 }}
diff --git a/app/templates/collections/detail/edit.hbs b/app/templates/collections/detail/edit.hbs
index 7705ee7..ae0f2b0 100644
--- a/app/templates/collections/detail/edit.hbs
+++ b/app/templates/collections/detail/edit.hbs
@@ -6,6 +6,7 @@
     collectionSpecies=CollectionSpeciesValidations
     datasheet=DatasheetValidations)
   options=options
+  hasMany=hasMany
   onSave=(action 'onSave')
   onCancel=(action 'onCancel')
 }}
diff --git a/app/templates/components/collection/create-container.hbs b/app/templates/components/collection/create-container.hbs
index 760be91..48d4f3c 100644
--- a/app/templates/components/collection/create-container.hbs
+++ b/app/templates/components/collection/create-container.hbs
@@ -95,7 +95,7 @@
       <table class="table">
         <caption>
           Species / Count Info
-          {{action-button isSuccess=true isXSmall=true label='+' onClick=(action 'addCollectionSpecies')}}
+          {{action-button isSuccess=true isXSmall=true label='+' onClick=(action 'addHasMany' 'collection-species' 'collectionSpecies')}}
         </caption>
         <thead>
           <tr>
@@ -138,7 +138,7 @@
                 {{/validated-field}}
               </td>
               <td class="col-md-2">
-                {{action-button isDanger=true isXSmall=true label='X' onClick=(action 'deleteCollectionSpecies' cs)}}
+                {{action-button isDanger=true isXSmall=true label='X' onClick=(action 'deleteHasMany' cs 'collectionSpecies')}}
               </td>
             </tr>
           {{/each}}
@@ -152,7 +152,7 @@
       <table class="table">
         <caption>
           Attachments
-          {{action-button isSuccess=true isXSmall=true label='+' onClick=(action 'addDatasheet')}}
+          {{action-button isSuccess=true isXSmall=true label='+' onClick=(action 'addHasMany' 'datasheet-attachment' 'datasheets')}}
         </caption>
         <thead>
           <tr>
@@ -173,7 +173,7 @@
                 {{/if}}
               </td>
               <td>
-                {{action-button isDanger=true isXSmall=true label='X' onClick=(action 'deleteDatasheet' d)}}
+                {{action-button isDanger=true isXSmall=true label='X' onClick=(action 'deleteHasMany' d 'datasheets')}}
               </td>
             </tr>
           {{/each}}