I den här delstudiet kommer vi att dyka djupt för att skapa en listahanteringsapp i Node.js och Geddy. Det här är den sista posten i serien, där vi kommer att fortsätta vårt att göra
föremål till MongoDB.
Som en snabb uppdatering, förra gången skapade vi vår att göra
resurs och gjorde ett arbete för att göra listansökan, men data fanns endast i minnet. I den här handledningen fixar vi det!
MongoDB är en NoSQL-dokumentbutikdatabas som skapats av folket över på 10gen. Det är en bra databas för Node-appar eftersom den lagrar data i ett JSON-liknande format, och dess frågor är skrivna i JavaScript. Vi använder det för vår app, så låt oss få den inrättad.
Gå till http://www.mongodb.org/downloads och hämta den senaste versionen för ditt operativsystem. Följ instruktionerna i readme därifrån. Se till att du kan börja mongod
(och fortsätt och lämna den igång under hela denna handledning)
Det är värt att notera att du måste ha mongo att köra när som helst du vill att din app ska köras. De flesta ställer upp detta för att starta med sin server med ett uppstartskript eller något liknande.
Gjort? okej, låt oss gå vidare.
För vår app använder vi en modul som wraps den mongodb-native databasdrivrutinen. Detta förenklar koden som vi producerar, så låt oss få den installerad. CD
in i din app och kör det här kommandot:
npm installera mongodb-wrapper
Om allt går bra borde du ha en mongodb-wrapper
katalog i din node_modules
katalog nu.
Mongo är en väldigt lätt DB att arbeta med; du behöver inte oroa dig för att konfigurera tabeller, kolumner eller databaser. Bara genom att ansluta till en databas skapar du en! Och bara genom att lägga till i en samling gör du en. Så låt oss sätta upp det här för vår app.
Vi behöver tillgång till vår DB-appövergripande, så låt oss konfigurera vår kod i config / init.js
. Öppna den upp; det ska se ut så här:
// Lägg till uncaught-exception handler i prod-liknande miljöer om (geddy.config.environment! = 'Utveckling') process.addListener ('uncaughtException', funktion (err) geddy.log.error (JSON.stringify ));); geddy.todos = []; geddy.model.adapter = ; geddy.model.adapter.Todo = kräver (process.cwd () + '/lib/model_adapters/todo').Todo;
Låt oss lägga till i vår db-kod längst upp (och ta bort geddy.todos-arrayen när vi är på den):
var mongo = kräver ("mongodb-wrapper"); geddy.db = mongo.db ("localhost", 27017, "todo"); geddy.db.collection ( 'todos'); // Lägg till uncaught-exception handler i prod-liknande miljöer om (geddy.config.environment! = 'Utveckling') process.addListener ('uncaughtException', funktion (err) geddy.log.error (JSON.stringify ));); geddy.model.adapter = ; geddy.model.adapter.Todo = kräver (process.cwd () + '/lib/model_adapters/todo').Todo;
Först kräver vi mongodb-wrapper
modul. Sedan ställer vi upp vår databas och lägger till en samling till den. Knappast någon uppsättning alls.
Geddy bryr sig inte om vilken data-backend du använder, så länge du har en modelladapter skriven för den. Det innebär att den enda koden som du måste ändra i din app för att få din att göra
s till en databas finns i modelladaptern. Det sägs att detta kommer att bli en fullständig omskrivning av adaptern, så om du vill behålla din gamla minnesapp-app runt, vill du kopiera koden till en annan mapp.
Öppna din modell-adapter (lib / model_adapters / todo.js
) och hitta spara
metod. Det borde se ut så här:
this.save = funktion (todo, opts, callback) if (typ av callback! = 'function') callback = function () ; var todoErrors = null; för (var jag i geddy.todos) // om det redan finns, spara det om (geddy.todos [i] .id == todo.id) geddy.todos [i] = todo; todoErrors = geddy.model.Todo.create (todo) .errors; returnera återuppringning (todoErrors, todo); todo.saved = true; geddy.todos.push (todo); returnera återuppringning (null, todo);
Gör det så här:
this.save = funktion (todo, opts, callback) // ibland behöver vi inte skicka en återuppringning om (typ av återuppringning! = 'funktion') callback = function () ; // Mongo gillar inte det när du skickar funktioner till det // så låt oss se till att vi bara använder egenskaperna cleanTodo = id: todo.id, sparade: todo.saved, title: todo.title, status : todo.status; // Dubbelkontroll för att se om det här är giltigt todo = geddy.model.Todo.create (cleanTodo); om (! todo.isValid ()) return callback (todo.errors, null); // Kontrollera om vi har det här att göra objekt redan geddy.db.todos.findOne (id: todo.id, funktion (err, doc) om (err) return callback (err, null); // om vi redan har objektet, uppdatera det med de nya värdena om (doc) geddy.db.todos.update (id: todo.id, cleanTodo, function (err, docs) return callback (todo.errors, todo);; // om vi inte redan har att göra objekt, spara en ny en annan todo.saved = true; geddy.db.todos.save (todo, function err, docs) return callback (err, docs);););
Bli inte för skämd av den här; Vi började med den mest komplicerade en först. Kom ihåg att vår spara
Metoden måste redovisa både nya att göra
s och uppdatera gamla att göra
s. Så låt oss gå igenom denna kod steg för steg.
Vi använder samma återuppringningskod som vi gjorde tidigare - om vi inte har en återuppringning skickad till oss, använd bara en tom funktion.
Sedan sanerar vi vår att göra
Artikel. Vi måste göra detta eftersom vår att göra
objektet har JavaScript-metoder på det (som spara
), och Mongo gillar inte det när du skickar objekt med metoder på dem. Så vi skapar bara ett nytt objekt med bara de egenskaper som vi bryr oss om det.
Då kontrollerar vi för att se om att göra
är giltig. Om det inte är så kallar vi återuppringningen med valideringsfel. Om det är fortsätter vi vidare.
Om vi redan har det här att göra
objekt i db, vi kontrollerar db för att se om a att göra
existerar. Det är här vi börjar använda mongodb-wrapper
modul. Det ger oss ett rent API för att arbeta med vår db. Här använder vi db.todos.findOne ()
Metod för att hitta ett enda dokument som stämmer överens med vår fråga. Vår fråga är ett enkelt js-objekt - vi letar efter ett dokument vars id
är samma som vår att göra
s id
. Om vi hittar en och det inte finns något fel använder vi db.todos.update ()
Metod för att uppdatera dokumentet med nya data. Om vi inte hittar en använder vi db.todos.save ()
Metod för att spara ett nytt dokument med att göra
objektets data.
I samtliga fall kallar vi en återuppringning när vi är färdiga, med eventuella fel som vi fick och de dokument som db återvände till oss skickades till det.
Ta en titt på Allt
metod ska det se ut så här:
this.all = function (callback) callback (null, geddy.todos);
Låt oss se ut så här:
this.all = function (callback) var todos = []; gedy.db.todos.find (). sort (status: -1, titel: 1). toArray (funktion (err, docs) // om det finns ett fel, returnera tidigt om (err) return callback err, null); // iterera genom docs och skapa modeller av dem för (var jag i docs) todos.push (geddy.model.Todo.create (docs [i])) returnera återuppringning (null, todos););
Mycket enklare än spara
metod tror du inte? Vi använder db.todos.find ()
metod för att få alla objekt i todos
samling. Vi använder monogdb-wrapper
s api till sortera
resultaten av status
(i avkänd alfabetisk ordning) och av titel
(i stigande alfabetisk ordning). Då skickar vi det till en matris, som utlöser frågan om att starta. När vi väl har fått tillbaka vår data kontrollerar vi om det finns några fel, om det finns, vi kallar återuppringningen med felet. Om det inte finns några fel fortsätter vi vidare.
Sedan gick vi igenom alla docs
(de dokument som mongo gav tillbaka till oss), skapa nya att göra
modell förekomster för var och en och tryck dem till en todos
array. När vi är färdiga där kallar vi återkallningen, som passerar in i todos
.
Ta en titt på "load" -metoden, det borde se ut så här:
this.load = funktion (id, återuppringning) för (var jag i geddy.todos) om (geddy.todos [i] .id == id) return callback (null, geddy.todos [i]); återuppringning (message: "För att inte hittas", null); ;
Låt oss se ut så här:
this.load = function (id, återuppringning) var todo; // hitta en todo i db geddy.db.todos.findOne (id: id, funktion (err, doc) // om det finns ett fel, returnera tidigt om (err) return callback (err, null) ; // om det finns ett dokument, skapa en modell av det om (doc) todo = geddy.model.Todo.create (doc); returnera återuppringning (null, todo);); ;
Den här är ännu enklare. Vi använder db.todos.findOne ()
metod igen. Den här gången är det bara vi behöver använda. Om vi har ett fel, kallar vi återkallningen med det, om inte fortsätter vi vidare (ser ett mönster här ännu?). Om vi har ett doc skapar vi en ny instans av att göra
modell och ringa backbacken med den. Det är det för den där.
Ta en titt på ta bort
metod nu ska det se ut så här:
this.remove = funktion (id, återuppringning) om (typ av återuppringning! = 'funktion') callback = function () ; för (var jag i geddy.todos) om (geddy.todos [i] .id == id) geddy.todos.splice (jag, 1); returnera återuppringning (null); returnera återuppringning (message: "För att inte hittas"); ;
Låt oss se ut så här:
this.remove = funktion (id, återuppringning) om (typ av återuppringning! = 'funktion') callback = function () ; geddy.db.todos.remove (id: id, funktion (err, res) callback (err););
Ta bort metoden är ännu kortare än den brukade vara. Vi använder db.todos.remove ()
Metod för att ta bort eventuella dokument med inlämnad id
och ring uppringningen med ett eventuellt fel.
Låt oss pröva vår app: CD
in i ditt projekt katalog och starta servern med geddy
. Skapa en ny att göra
. Försök att redigera det, misslyckas med några valideringar och försök att ta bort det. Allt fungerar!
Jag hoppas att du har haft lust om Node.js, MongoDB och särskilt Geddy. Jag är säker på att du nu har en miljon idéer för vad du kan bygga med det, och jag skulle gärna höra om dem. Som alltid, om du har några frågor, lämna en kommentar här eller öppna ett problem på github.