2017-05-04 2 views
0

Ich bin ziemlich neu zu Mungo/Express. Was ich kämpfe, ist zu versuchen, neue Daten vom HTML-Formular zu aktualisieren und es in Datenbank zu speichern, die Verweise hat. Ich habe ein Geschäftsmodell mit Standortbezug zum Standortmodell. Hier sind die Codes.Update-Datenbank mit mehreren Referenz-Datenbank-Probleme

edit.ejs

<div class="container"> 
    <div class="form-container"> 
     <form action="/<%= bus._id %>?_method=PUT" method="POST"> 
      <!-- business info --> 
      <h3>Business Information</h3> 
      <input class="form-input" type="input" name="bus[logo]" value="<%= bus.logo %>"> 
      <input class="form-input" type="input" name="bus[name]" value="<%= bus.name %>"> 
      <% bus.location.forEach(function(location) { %> 
      <input class="form-input" type="input" name="bus.location[street]" value="<%= location.street %>"> 
      <input class="form-input" type="input" name="bus.location[city]" value="<%= location.city %>"> 
      <div class="state-input"> 
       <select class="form-inline" name="bus.location[state]"> 
        <option value="" disabled selected><%= location.state %></option> 
        <option value="AL">Alabama</option> 
        ... 
        <option value="WY">Wyoming</option> 
       </select> 
      </div><!--State-input --> 
      <input class="form-inline" type="input" name="bus.location[zipcode]" value="<%= location.zipcode %>"> 
      <% }) %> 
      <!--Contact info--> 
      <h4>Contact Information</h4> 
      <% bus.contact.forEach(function(contact) { %> 
      <input class="form-input" type="url" name="bus[url]" value="<%= bus.url %>"> 
      <input class="form-input" type="email" name="bus.contact[email]" value="<%= contact.email %>"> 
      <input class="form-input" type="tel" name="bus.contact[phone]" value="<%= contact.phone %>"> 
      <input class="form-input" type="input" name="bus.contact[twitter]" value= "<%= contact.twitter %>"> 
      <input class="form-input" type="input" name="bus.contact[facebook]" value="<%= contact.facebook %>"> 
      <input class="form-input" type="input" name="bus.contact[instagram]" value="<%= contact.instagram %>"> 
      <% }) %> 

index.js - bearbeiten Routen

//(edit.ejs) Edit Route 
app.get('/:id/edit', function(req, res) { 
    Business.findById(req.params.id) 
    .populate('location') 
    .populate('contact') 
    .populate('images') 
    .exec(function(err, bus) { 
     if(err) { 
      console.log(err); 
     } else { 
      res.render('edit', {bus:bus}); 
     } 
    }); 
}); 
app.put('/:id', function(req, res) { 
    Business.findByIdAndUpdate(req.params.id, req.body.bus, function(err, bus) { 
     if(err) { 
      console.log(err); 
      res.redirect('/' + req.params.id + '/edit'); 
     } else { 
      res.redirect('/' + req.params.id); 
     } 
    }); 
}); 

Das Geschäft (Bus) aktualisiert schön aber bus.location nicht aktualisiert. Geschäftsmodell

//----------------------------------------------------------------------------\\ 
var mongoose = require('mongoose'); 
//----------------------------------------------------------------------------\\ 
var busSchema = new mongoose.Schema({ 
    name: String, 
    type: String, 
    logo: String, 
    desc: String, 
    subs: Number, 
    video: String, 
    url: String, 
    firstRun: Boolean, 
    location:[ 
     { 
     type: mongoose.Schema.Types.ObjectId, 
     ref: 'Location' 
     } 
    ], 
    contact:[ 
     { 
     type: mongoose.Schema.Types.ObjectId, 
     ref: 'Contact' 
     } 
    ], 
    images:[ 
     { 
     type: mongoose.Schema.Types.ObjectId, 
     ref: 'Image' 
     } 
    ], 
    comments:[ 
     { 
     type: mongoose.Schema.Types.ObjectId, 
     ref: 'Comment' 
     } 
    ], 
    created: { 
     type: Date, default: Date.now 
    } 
}); 
//----------------------------------------------------------------------------\\ 
module.exports = mongoose.model('Business', busSchema); 

Location Modell

//----------------------------------------------------------------------------\\ 
var mongoose = require('mongoose'); 
//----------------------------------------------------------------------------\\ 
var locSchema = new mongoose.Schema(
    { 
     street: String, 
     city: String, 
     state: String, 
     zipcode: Number 
    } 
); 
//----------------------------------------------------------------------------\\ 
module.exports = mongoose.model('Location', locSchema); 
+0

Willkommen bei Stack Overflow. Was ist der Fehler? Wie ist der Datenfluss? Kannst du deinen Code erklären? Seien Sie immer spezifisch und machen Sie sich vor der Anfrage die größte Mühe, und behandeln Sie Stack Overflow nicht als Repository für Lernprogramme. Stack Overflow ist eine Frage-Antwort-Website, kein Code-Schreibdienst. Bitte [siehe hier] (https://stackoverflow.com/help/how-to-ask) um zu erfahren, wie man effektive Fragen schreibt. – Teocci

Antwort

0

Business, Location und Contact verschiedenen Sammlungen sind.

findByIdAndUpdate aktualisiert nur eine Sammlung, die Ihre ist insbesondere Business. Um die anderen Sammlungen zu aktualisieren, müssen Sie Vorgänge für diese Sammlungen durchführen.

Wenn Sie versuchen, "vorhandene" Standorte und Kontakte zu aktualisieren, müssen Sie auch ihre IDs angeben. Außerdem haben Sie ein "Array" von Standorten und Kontakten, so dass Sie zusätzliche [] zu Ihren Namen benötigen.

<% bus.location.forEach(function(location, i) { %> 
    <input type="hidden" name="location[<?= i ?>][id]" value="<%= location.id %>"> 
    <input class="form-input" type="input" name="location[<?= i ?>][street]" value="<%= location.street %>"> 
    <!-- etc --> 
<% }) %> 

<% bus.contact.forEach(function(contact, i) { %> 
    <input type="hidden" name="contact[<?= i ?>][id]" value="<%= contact.id %>"> 
    <input class="form-input" type="email" name="contact[<?= i ?>][email]" value="<%= contact.email %>"> 
    <!-- etc --> 
<% }) %> 

Aus meiner (und others) Erfahrung, ich glaube nicht, ist es möglich, mehrere Dokumente auf einmal zu aktualisieren. Dies bedeutet, dass Sie in Ihrem Routen-Handler jedes Element in den angegebenen Arrays durchlaufen und einzeln aktualisieren müssen. Die Antwort in dem anderen Beitrag ist jedoch nicht ganz richtig IMO, da Sie keine synchrone forEach asynchrone Mungose-Operationen verwenden sollten, da dies zu unerwartetem Verhalten führen wird.

Sie haben drei Hauptaufgaben zu erledigen: Aktualisieren des Unternehmens, Aktualisieren ihrer vorhandenen Standorte und Aktualisieren ihrer vorhandenen Kontakte.

Ich mag async.js verwenden, um mehrere asynchrone Operationen durchzuführen. In Ihrem speziellen Fall würde ich für jede Aufgabe und async.eachSeries verwenden, um eine Operation für jedes Element Ihrer Arrays zu tun.

Warnung Dies ist nicht getestet, aber es würde wie folgt aussehen:

app.put('/:id', function(req, res) { 

    console.log(req.body.bus); 
    console.log(req.body.location); // should be an array of objects 
    console.log(req.body.contact); // should be an array of objects 

    // perform each task one by one 
    async.series([ 
     function updateBusiness (done) { 
      // you need to always call the callback i.e. done to indicate the task is "done" 
      // - if you pass an error as an argument, it means the task failed and stop everything 
      // - otherwise, move onto the next task 

      /*Business.findByIdAndUpdate(req.params.id, req.body.bus, function (err) { 
       if (err) { 
        return done(err); // task failed and stop everything 
       } 
       done(); // task went well and proceed to the next task 
      });*/ 

      // simplified 
      Business.findByIdAndUpdate(req.params.id, req.body.bus, done); 
     }, 
     function updateLocations (done) { 
      // find and update each location 
      async.eachSeries(req.body.location || [], function (location, done2) { 
       Location.findByIdAndUpdate(location.id, location, done2); 
      }, done); 
     }, 
     function updateContacts (done) { 
      // find and update each contact 
      async.eachSeries(req.body.contact || [], function (contact, done2) { 
       Contact.findByIdAndUpdate(contact.id, contact, done2); 
      }, done); 
     } 
    ], function allDone (err) { 
     // a task failed somewhere 
     if (err) { 
      console.log(err); 
      res.redirect('/' + req.params.id + '/edit'); 
     // all tasks were completed 
     } else { 
      res.redirect('/' + req.params.id); 
     } 
    }); 
}); 

Wenn ein Fehler auftritt, sehen Sie sich die Konsolenprotokolle.

+0

Ich konnte herausfinden, was mit meiner Codestruktur falsch gelaufen ist, als Sie empfohlen wurde, weitere [] IDs für Kontakt und Standort hinzuzufügen. Ich bin nicht vertraut mit async.js Werkzeug, aber beabsichtige, das zu untersuchen. Vielen Dank! –

+0

Neugierig: Mit Ihrer Änderung, hat es tatsächlich speichern nur mit dem 'Business.findByIdAndUpdate'?Oder musstest du mehr tun? – Mikey

+0

Ja, ich konnte mit Business.findByIdAndUpdate speichern und dann am Ende des Codes umleiten. Bezüglich Kontakt und Standort musste ich findByIdAndUpdate für Kontakt und Standort einzeln mit forEach verwenden. Nimmt mehrere Zeilen auf, möchte aber herausfinden, wie sie am besten umgestaltet werden können. Wie ich schon sagte, ziemlich neu und immer noch lernen das Handwerk. Aber ich konnte es mit Ihrer Hilfe zur Arbeit bringen! –