Fortsetter en Todo liste med MongoDB og Geddy

I denne tre del-opplæringen vil vi dykke dypt inn i å lage en listeliste i Node.js og Geddy. Dette er den siste oppføringen i serien, hvor vi vil fortsette vår å gjøre elementer til MongoDB.

Som en rask oppdatering, sist gang, opprettet vi vår å gjøre ressurs og gjorde en jobb å gjøre liste søknad, men dataene eksisterte bare i minnet. I denne opplæringen vil vi fikse det!


Intro til MongoDB

MongoDB er en NoSQL dokument butikk database opprettet av folk over på 10gen. Det er en flott database for Node-applikasjoner fordi den lagrer dataene i et JSON-lignende format allerede, og forespørgene er skrevet i JavaScript. Vi bruker det til vår app, så la oss få det satt opp.

Installere MongoDB

Gå til http://www.mongodb.org/downloads og last ned den nyeste versjonen for operativsystemet ditt. Følg instruksjonene i readme derfra. Pass på at du kan starte mongod (og fortsett og la det gå i gang i løpet av denne opplæringen)

Det er verdt å merke seg at du må ha mongo kjører når du vil at appen skal kjøre. De fleste settes opp for å starte opp med serveren ved hjelp av et oppstartskript eller noe som helst.

Ferdig? ok, la oss gå videre.

MongoDB-Wrapper

For vår app, bruker vi en modul som bryter inn den mongodb-native database driveren. Dette forenkler koden vi produserer, så la oss få det installert. cd inn i appen din og kjør denne kommandoen:

npm installere mongodb-wrapper

Hvis alt går bra, bør du ha en mongodb-wrapper katalog i din node_modules katalog nå.


Sette opp databasen

Mongo er en veldig enkel DB å jobbe med; du trenger ikke å bekymre deg for å sette opp tabeller, kolonner eller databaser. Bare ved å koble til en database, oppretter du en! Og bare ved å legge til i en samling, lager du en. Så la oss sette opp dette for appen vår.

Redigerer init.js-filen

Vi trenger tilgang til vår DB-applikasjon, så la oss sette opp koden vår config / init.js. Åpne den opp; det skal se slik ut:

// Legg til uncaught-exception handler i prod-lignende omgivelser hvis (geddy.config.environment! = 'Development') process.addListener ('uncaughtException', funksjon (err) geddy.log.error (JSON.stringify )););  geddy.todos = []; geddy.model.adapter = ; geddy.model.adapter.Todo = kreve (process.cwd () + '/lib/model_adapters/todo').Todo;

La oss legge til i vår db-kode øverst (og fjern geddy.todos-arrayet mens vi er på det):

var mongo = krever ('mongodb-wrapper'); geddy.db = mongo.db ('localhost', 27017, 'todo'); geddy.db.collection ( 'todos'); // Legg til uncaught-exception handler i prod-lignende omgivelser hvis (geddy.config.environment! = 'Development') process.addListener ('uncaughtException', funksjon (err) geddy.log.error (JSON.stringify )););  geddy.model.adapter = ; geddy.model.adapter.Todo = kreve (process.cwd () + '/lib/model_adapters/todo').Todo;

Først krever vi mongodb-wrapper modul. Deretter setter vi opp vår database, og legger til en samling til den. Knapt noen satt opp i det hele tatt.


Skriv om modell-adapteren din

Geddy bryr seg ikke om hvilken data-backend du bruker, så lenge du har en modelladapter skrevet for den. Dette betyr at den eneste koden du må endre i appen din for å få din å gjøres til en database er i modelladapteren. Når det er sagt, vil dette bli en fullstendig omskrivning av adapteren, så hvis du vil beholde den gamle appen i minnet rundt, vil du kopiere koden til en annen katalog.

Redigerer lagre metode

Åpne opp din modelladapter (lib / model_adapters / todo.js) og finn lagre metode. Det skal se slik ut:

this.save = funksjon (todo, ops, tilbakeringing) if (type tilbakering! = 'funksjon') callback = function () ;  var todoErrors = null; for (var jeg i geddy.todos) // hvis den allerede er der, lagre den hvis (geddy.todos [i] .id == todo.id) geddy.todos [i] = todo; todoErrors = geddy.model.Todo.create (todo) .errors; returnere tilbakeringing (todoErrors, todo);  todo.saved = true; geddy.todos.push (todo); returnere tilbakeringing (null, todo); 

Få det til å se slik ut:

this.save = funksjon (todo, ops, tilbakeringing) // noen ganger trenger vi ikke å sende tilbakekalling hvis (type tilbakering! = 'funksjon') callback = function () ;  // Mongo liker ikke det når du sender funksjoner til det // så la oss sørge for at vi bare bruker egenskapene cleanTodo = id: todo.id, lagret: todo.saved, title: todo.title, status : todo.status; // Dobbeltkryss for å se om denne tingen er gyldig todo = geddy.model.Todo.create (cleanTodo); hvis (! todo.isValid ()) return callback (todo.errors, null);  // Sjekk om vi har dette til å gjøre elementet allerede geddy.db.todos.findOne (id: todo.id, funksjon (feil, doc) hvis (err) return callback (feil, null);  // hvis vi allerede har å gjøre elementet, oppdater det med de nye verdiene hvis (doc) geddy.db.todos.update (id: todo.id, cleanTodo, funksjon (feil, docs) return callback (todo.errors, todo);; // hvis vi ikke allerede har å gjøre elementet, lagre et nytt annet todo.saved = true; geddy.db.todos.save (todo, function feil, docs) return callback (feil, docs););); 

Ikke vær for skremt av denne; Vi startet med den mest komplekse en først. Husk at vår lagre Metoden må ta hensyn til både nye å gjøres og oppdatere gamle å gjøres. Så la oss gå gjennom denne koden trinnvis.

Vi bruker samme tilbakeringingsnummer som vi gjorde før - hvis vi ikke har tilbakekalling til oss, bruk bare en tom funksjon.

Så sanitiserer vi vår å gjøre punkt. Vi må gjøre dette fordi vår å gjøre objektet har JavaScript-metoder på det (som lagre), og Mongo liker ikke det når du sender det til objekter med metoder på dem. Så vi lager bare et nytt objekt med bare egenskapene vi bryr oss om.

Så sjekker vi for å se om å gjøre er gyldig. Hvis det ikke er det, kaller vi tilbakeringingen med valideringsfeilene. Hvis det er, fortsetter vi videre.

Hvis vi allerede har dette å gjøre element i db, vi sjekker db for å se om a å gjøre eksisterer. Det er her vi begynner å bruke mongodb-wrapper modul. Det gir oss en ren API for å jobbe med vår db. Her bruker vi db.todos.findOne () Metode for å finne et enkelt dokument som tilfredsstiller spørringen. Vår søk er et enkelt js-objekt - vi leter etter et dokument hvis id er det samme som vår å gjøres id. Hvis vi finner en og det ikke er en feil, bruker vi db.todos.update () Metode for å oppdatere dokumentet med de nye dataene. Hvis vi ikke finner en, bruker vi db.todos.save () metode for å lagre et nytt dokument med å gjøre elementets data.

I alle tilfeller kaller vi en tilbakeringing når vi er ferdige, med eventuelle feil vi har og dokumentene som db returnerte til oss blir sendt videre til det.

Redigerer hele metoden

Ta en titt på alle metode, det skal se slik ut:

this.all = funksjon (tilbakeringing) tilbakeringing (null, geddy.todos); 

La oss få det til å se slik ut:

this.all = funksjon (tilbakeringing) var todos = []; gedy.db.todos.find (). sort (status: -1, tittel: 1). toArray (funksjon (feil, docs) // hvis det oppstår en feil, returner tidlig hvis (feil) return callback err, null); // iterate gjennom docs og lage modeller ut av dem for (var jeg i docs) todos.push (geddy.model.Todo.create (docs [i])) returnere tilbakeringing (null, todos);); 

Mye enklere enn lagre metode, tror du ikke? Vi bruker db.todos.find () metode for å få alle elementene i todos samling. Vi bruker monogdb-wrappers api til sortere resultatene av status (i alfabetisk rekkefølge) og ved tittel (i stigende alfabetisk rekkefølge). Deretter sender vi det til en matrise, som utløser spørringen for å starte. Når vi får tilbake dataene våre, kontrollerer vi for å se om det er noen feil, hvis det er det, kalder vi tilbakekallingen med feilen. Hvis det ikke er noen feil fortsetter vi videre.

Så løp vi gjennom alle docs (dokumentene som mongo ga tilbake til oss), opprett ny å gjøre modell forekomster for hver av dem, og skyv dem til en todos array. Når vi er ferdige der, kaller vi tilbakeringingen, som går forbi todos.

Redigerer belastningsmetoden

Ta en titt på 'last'-metoden, det skal se slik ut:

 this.load = funksjon (id, tilbakeringing) for (var jeg i geddy.todos) hvis (geddy.todos [i] .id == id) return callback (null, geddy.todos [i]);  tilbakeringing (melding: "Ikke funnet", null); ;

La oss få det til å se slik ut:

this.load = funksjon (id, tilbakeringing) var todo; // finne en todo i db geddy.db.todos.findOne (id: id, funksjon (feil, doc) // hvis det er en feil, returner tidlig hvis (feil) return callback (feil, null) ; // hvis det er en doc, lage en modell ut av det hvis (doc) todo = geddy.model.Todo.create (doc); returnere tilbakeringing (null, todo);); ;

Denne er enda enklere. Vi bruker db.todos.findOne () metode igjen. Denne gangen er det alt vi må bruke skjønt. Hvis vi har en feil, kaller vi tilbakeringingen med den, hvis ikke, fortsetter vi videre (se et mønster her ennå?). Hvis vi har en doc, oppretter vi en ny forekomst av å gjøre modell og ring tilbakekallingen med den. Det er det for den.

Redigerer fjernmetoden

Ta en titt på fjerne Metoden nå, det skal se slik ut:

this.remove = funksjon (id, tilbakeringing) hvis (type tilbakering! = 'funksjon') callback = funksjon () ;  for (var jeg i geddy.todos) hvis (geddy.todos [i] .id == id) geddy.todos.splice (jeg, 1); returnere tilbakeringing (null);  returnere tilbakeringing (melding: "Ikke funnet"); ;

La oss få det til å se slik ut:

this.remove = funksjon (id, tilbakeringing) hvis (type tilbakering! = 'funksjon') callback = funksjon () ;  geddy.db.todos.remove (id: id, funksjon (feil, res) callback (err);); 

Fjernmetoden er enda kortere enn den pleide å være. Vi bruker db.todos.remove () metode for å fjerne eventuelle dokumenter med passet inn id og ring tilbakeringingen med en feil (hvis noen).


Tid for magien

La oss teste vår app: cd inn i prosjektets katalog og start serveren med Geddy. Lage en ny å gjøre. Prøv å redigere det, få det til å mislykkes noen valideringer, og prøv å fjerne det. Alt fungerer!


Konklusjon

Jeg håper du har likt å lære om Node.js, MongoDB og spesielt Geddy. Jeg er sikker på at du nå har en million ideer for hva du kan bygge med det, og jeg vil gjerne høre om dem. Som alltid, hvis du har noen spørsmål, legg igjen en kommentar her eller åpne et problem på github.