Persistere in una lista di cose da fare con MongoDB e Geddy

In questo tutorial in tre parti, ci immergeremo profondamente nella creazione di un'app per la gestione delle liste in Node.js e Geddy. Questa è l'ultima voce della serie, dove continueremo a persistere fare elementi per MongoDB.

Come aggiornamento rapido, l'ultima volta, abbiamo creato il nostro fare risorsa e ha fatto un lavoro per fare l'elenco dell'applicazione, ma i dati esistevano solo in memoria. In questo tutorial, lo risolveremo!


Introduzione a MongoDB

MongoDB è un database di archivio di documenti NoSQL creato dagli utenti oltre a 10gen. È un ottimo database per le app di Node perché memorizza già i suoi dati in un formato simile a JSON e le sue query sono scritte in JavaScript. Lo useremo per la nostra app, quindi sistemiamolo.

Installare MongoDB

Vai a http://www.mongodb.org/downloads e scarica l'ultima versione per il tuo sistema operativo. Segui le istruzioni nel readme da lì. Assicurati di poter iniziare mongod (e vai avanti e lasciarlo in esecuzione per la durata di questo tutorial)

Vale la pena notare che è necessario avere mongo in esecuzione ogni volta che si desidera eseguire l'app. La maggior parte delle persone lo imposta per avviarsi con il proprio server usando uno script upstart o qualcosa del genere.

Fatto? va bene, andiamo avanti.

MongoDB-Wrapper

Per la nostra app, utilizzeremo un modulo che include il driver del database nativo mongodb. Questo semplifica enormemente il codice che produrremo, quindi installiamolo. CD nella tua app ed esegui questo comando:

npm install mongodb-wrapper

Se tutto va bene dovresti avere un MongoDB-wrapper directory nel tuo node_modules directory ora.


Impostazione del database

Mongo è un DB molto semplice con cui lavorare; non devi preoccuparti di configurare tabelle, colonne o database. Semplicemente collegandoti a un database, ne crei uno! E aggiungendo a una raccolta, ne fai uno. Quindi sistemiamolo per la nostra app.

Modifica del file init.js

Avremo bisogno di accedere alla nostra applicazione DB, quindi installiamo il nostro codice config / Init.js. Aprilo; Dovrebbe sembrare come questo:

// Aggiungi il gestore di eccezioni non rilevate negli ambienti prod-if se (geddy.config.environment! = 'Sviluppo') process.addListener ('uncaughtException', function (err) geddy.log.error (JSON.stringify (err )););  geddy.todos = []; geddy.model.adapter = ; geddy.model.adapter.Todo = require (process.cwd () + '/lib/model_adapters/todo').Todo;

Aggiungiamo il nostro codice db all'inizio (e rimuoviamo l'array geddy.todos mentre ci siamo):

var mongo = require ('mongodb-wrapper'); geddy.db = mongo.db ('localhost', 27017, 'todo'); geddy.db.collection ( 'Todos'); // Aggiungi il gestore di eccezioni non rilevate negli ambienti prod-if se (geddy.config.environment! = 'Sviluppo') process.addListener ('uncaughtException', function (err) geddy.log.error (JSON.stringify (err )););  geddy.model.adapter = ; geddy.model.adapter.Todo = require (process.cwd () + '/lib/model_adapters/todo').Todo;

Innanzitutto, richiediamo il MongoDB-wrapper modulo. Quindi, impostiamo il nostro database e aggiungiamo una collezione. Quasi nessun set up.


Riscrivere l'adattatore del modello

A Geddy non interessa davvero quale backend di dati si usi, a patto che sia stato scritto un adattatore per il modello. Ciò significa che l'unico codice che dovrai modificare nella tua app per ottenere il tuo fares in un database è nel modello-adattatore. Detto questo, questa sarà una completa riscrittura dell'adattatore, quindi se vuoi mantenere la tua vecchia app in-memory, dovrai copiare il codice in un'altra directory.

Modifica del metodo di salvataggio

Apri il tuo adattatore per il modello (lib / model_adapters / todo.js) e trova il salvare metodo. Dovrebbe assomigliare a qualcosa di simile a questo:

this.save = function (todo, opts, callback) if (typeof callback! = 'function') callback = function () ;  var todoErrors = null; per (var i in geddy.todos) // se è già lì, salvalo se (geddy.todos [i] .id == todo.id) geddy.todos [i] = todo; todoErrors = geddy.model.Todo.create (todo) .errors; return callback (todoErrors, todo);  todo.saved = true; geddy.todos.push (todo); return callback (null, todo); 

Assomigli a questo:

this.save = function (todo, opts, callback) // a volte non è necessario passare una richiamata se (typeof callback! = 'function') callback = function () ;  // A Mongo non piace quando si inviano funzioni ad esso // quindi assicuriamoci di utilizzare solo le proprietà cleanTodo = id: todo.id, salvato: todo.saved, titolo: todo.title, stato : todo.status; // Verifica due volte per vedere se questa cosa è valida todo = geddy.model.Todo.create (cleanTodo); if (! todo.isValid ()) return callback (todo.errors, null);  // Controlla se abbiamo già questo oggetto geddy.db.todos.findOne (id: todo.id, function (err, doc) if (err) return callback (err, null);  // se abbiamo già l'oggetto da fare, aggiornalo con i nuovi valori if (doc) geddy.db.todos.update (id: todo.id, cleanTodo, function (err, docs) return callback (todo.errors, todo);); // se non abbiamo già l'elemento di fare, salvarne uno nuovo todo.saved = true; geddy.db.todos.save (todo, function ( err, docs) return callback (err, docs););); 

Non essere troppo scoraggiato da questo; abbiamo iniziato con il più complesso per primo. Ricorda che il nostro salvare il metodo deve tener conto di entrambi i nuovi fares e l'aggiornamento vecchio fareS. Quindi passiamo attraverso questo codice passo dopo passo.

Usiamo lo stesso codice di callback come facevamo prima - se non ci è stata passata una callback, basta usare una funzione vuota.

Quindi disinfettiamo il nostro fare articolo. Dobbiamo farlo perché nostro fare oggetto ha metodi JavaScript su di esso (come salvare), e a Mongo non piace quando gli passi oggetti con metodi su di essi. Quindi creiamo un nuovo oggetto con solo le proprietà che ci interessano.

Quindi, controlliamo per vedere se il fare è valido. In caso contrario, chiamiamo la richiamata con gli errori di convalida. Se lo è, proseguiamo.

Nel caso in cui già abbiamo questo fare elemento nel db, controlliamo il db per vedere se a fare esiste. Questo è dove iniziamo a usare il MongoDB-wrapper modulo. Ci fornisce un'API pulita per lavorare con il nostro db. Qui stiamo usando il db.todos.findOne () metodo per trovare un singolo documento che soddisfi la nostra query. La nostra query è un semplice oggetto js - stiamo cercando un documento di cui id è uguale al nostro fareS id. Se ne troviamo uno e non c'è un errore, usiamo il db.todos.update () metodo per aggiornare il documento con i nuovi dati. Se non lo troviamo, usiamo il db.todos.save () metodo per salvare un nuovo documento con il fare dati dell'articolo.

In tutti i casi, richiamiamo una richiamata quando abbiamo finito, con tutti gli errori che abbiamo ricevuto e i documenti che il db ci ha restituito passandoci sopra.

Modifica del metodo all

Dai un'occhiata al tutti metodo, dovrebbe assomigliare a questo:

this.all = function (callback) callback (null, geddy.todos); 

Facciamo in modo che assomigli a questo:

this.all = function (callback) var todos = []; geddy.db.todos.find (). sort (status: -1, title: 1). toArray (function (err, docs) // se c'è un errore, torna presto se (err) return callback ( err, null); // itera attraverso i documenti e crea modelli per (var i in docs) todos.push (geddy.model.Todo.create (docs [i])) richiama callback (null, todos);); 

Molto più semplice del salvare metodo, non credi? Noi usiamo il db.todos.find () metodo per ottenere tutti gli elementi nel Todos collezione. Stiamo usando monogdb-wrapperApi a ordinare i risultati di stato (decrescente in ordine alfabetico) e di titolo (in ordine alfabetico crescente). Quindi lo inviamo a un array, che attiva la query per l'avvio. Una volta recuperati i nostri dati, controlliamo se ci sono errori, se ci sono, chiamiamo il callback con l'errore. Se non ci sono errori continuiamo.

Quindi, passiamo attraverso tutto il docs (i documenti che mongo ci ha restituito), creare nuovi fare esempi di modelli per ognuno di essi e li spingo a a Todos array. Quando abbiamo finito, chiamiamo il callback, passando il Todos.

Modifica del metodo di caricamento

Dai un'occhiata al metodo 'load', dovrebbe assomigliare a questo:

 this.load = function (id, callback) for (var i in geddy.todos) if (geddy.todos [i] .id == id) return callback (null, geddy.todos [i]);  callback (message: "To Do not found", null); ;

Facciamo in modo che assomigli a questo:

this.load = function (id, callback) var todo; // trova un todo nel db geddy.db.todos.findOne (id: id, function (err, doc) // se c'è un errore, torna presto se (err) return callback (err, null) ; // se c'è un documento, creane un modello se (doc) todo = geddy.model.Todo.create (doc); return callback (null, todo);); ;

Questo è ancora più semplice. Noi usiamo il db.todos.findOne () metodo di nuovo. Questa volta, è tutto ciò che dobbiamo usare però. Se abbiamo un errore, chiamiamo il callback con esso, in caso contrario, continuiamo (vedendo uno schema ancora qui?). Se abbiamo un documento, creiamo una nuova istanza di fare modella e chiama il callback con esso. Questo è tutto per quello.

Modifica del metodo di rimozione

Dai un'occhiata al rimuovere metodo ora, dovrebbe assomigliare a questo:

this.remove = function (id, callback) if (typeof callback! = 'function') callback = function () ;  for (var i in geddy.todos) if (geddy.todos [i] .id == id) geddy.todos.splice (i, 1); return callback (null);  return callback (message: "To Do not found"); ;

Facciamo in modo che assomigli a questo:

this.remove = function (id, callback) if (typeof callback! = 'function') callback = function () ;  geddy.db.todos.remove (id: id, function (err, res) callback (err);); 

Il metodo di rimozione è ancora più corto di quello che era un tempo. Noi usiamo il db.todos.remove () metodo per rimuovere tutti i documenti con il passato id e chiama la richiamata con un errore (se presente).


Tempo per la magia

Andiamo a testare la nostra app: CD nella directory del progetto e avviare il server con Geddy. Crea un nuovo fare. Prova a modificarlo, a fallire alcune convalide e prova a rimuoverlo. Funziona tutto!


Conclusione

Spero ti sia piaciuto conoscere Node.js, MongoDB e soprattutto Geddy. Sono sicuro che ora hai un milione di idee per quello che potresti costruire con esso, e mi piacerebbe sentir parlare di loro. Come sempre, se avete domande, lasciate un commento qui o aprite un problema su github.