Persister dans une liste de tâches avec MongoDB et Geddy

Dans ce didacticiel en trois parties, nous allons nous plonger dans la création d'une application de gestion de liste de tâches dans Node.js et Geddy. Ceci est la dernière entrée de la série, où nous allons continuer notre faire articles à MongoDB.

Pour rappel, la dernière fois, nous avons créé notre faire ressource et fait une application de travail à faire, mais les données n'existaient que dans la mémoire. Dans ce tutoriel, nous allons résoudre ce problème!


Introduction à MongoDB

MongoDB est une base de données de magasin de documents NoSQL créée par les utilisateurs de 10gen. C'est une excellente base de données pour les applications Node car elle stocke déjà ses données dans un format semblable à JSON et ses requêtes sont écrites en JavaScript. Nous allons l'utiliser pour notre application, alors mettons-le en place.

Installer MongoDB

Allez sur http://www.mongodb.org/downloads et téléchargez la dernière version pour votre système d'exploitation. Suivez les instructions du fichier readme à partir de là. Assurez-vous que vous pouvez commencer Mongod (et continuez et laissez-le en marche pendant toute la durée de ce tutoriel)

Il est à noter que vous aurez besoin de faire fonctionner mongo à tout moment si vous voulez que votre application soit exécutée. La plupart des gens le configurent pour démarrer avec leur serveur en utilisant un script de mise à jour ou quelque chose du genre..

Terminé? d'accord, passons à autre chose.

MongoDB-Wrapper

Pour notre application, nous utiliserons un module qui encapsule le pilote de base de données mongodb-native. Cela simplifie grandement le code que nous allons produire, alors installons-le. CD dans votre application et exécutez cette commande:

npm installez mongodb-wrapper

Si tout se passe bien, vous devriez avoir un mongodb-wrapper répertoire dans votre node_modules répertoire maintenant.


Configuration de votre base de données

Mongo est une base de données très facile à utiliser. vous n'avez pas à vous préoccuper de la configuration de tables, de colonnes ou de bases de données. En vous connectant simplement à une base de données, vous en créez une! Et simplement en ajoutant à une collection, vous en créez une. Alors mettons cela en place pour notre application.

Modification de votre fichier init.js

Nous allons avoir besoin d'accéder à notre base de données à l'échelle de l'application, alors configurons notre code dans config / init.js. Ouvrez-le; ça devrait ressembler à ça:

// Ajouter un gestionnaire d'exception non capturée dans des environnements de type prod si (geddy.config.environment! = 'Development') 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;

Ajoutons notre code de base de données tout en haut (et supprimons le tableau geddy.todos tant que nous y sommes):

var mongo = require ('mongodb-wrapper'); geddy.db = mongo.db ('localhost', 27017, 'todo'); geddy.db.collection ('todos'); // Ajouter un gestionnaire d'exception non capturée dans des environnements de type prod si (geddy.config.environment! = 'Development') 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;

Premièrement, nous avons besoin de mongodb-wrapper module. Ensuite, nous configurons notre base de données et y ajoutons une collection. Pas du tout mis en place.


Réécrire votre modèle d'adaptateur

Geddy ne se soucie pas vraiment du backend de données que vous utilisez, tant que vous avez un adaptateur de modèle écrit pour cela. Cela signifie que le seul code que vous devrez modifier dans votre application pour obtenir votre faires dans une base de données se trouve dans l'adaptateur de modèle. Cela dit, il s'agira d'une réécriture complète de l'adaptateur. Par conséquent, si vous souhaitez conserver votre ancienne application en mémoire, copiez le code dans un autre répertoire..

Modification de votre méthode de sauvegarde

Ouvrez votre adaptateur de modèle (lib / model_adapters / todo.js) et trouver le enregistrer méthode. Ça devrait ressembler a quelque chose comme ca:

this.save = function (todo, opts, callback) if (type de callback! = 'fonction') callback = function () ;  var todoErrors = null; for (var i dans geddy.todos) // s'il y en a déjà, enregistrez-le si (geddy.todos [i] .id == todo.id) geddy.todos [i] = todo; todoErrors = geddy.model.Todo.create (todo) .errors; renvoyer un rappel (todoErrors, todo);  todo.saved = true; geddy.todos.push (todo); retourne le rappel (null, todo); 

Faites-le ressembler à ceci:

this.save = function (todo, opts, callback) // nous n'avons parfois pas besoin de passer un callback if (typeof callback! = 'fonction') callback = function () ;  // Mongo n'aime pas ça quand vous lui envoyez des fonctions // alors assurons-nous que nous n'utilisons que les propriétés cleanTodo = id: todo.id, sauvegardé: todo.saved, title: todo.title, status : todo.status; // Vérifiez que cette chose est valide todo = geddy.model.Todo.create (cleanTodo); if (! todo.isValid ()) retour callback (todo.errors, null);  // Vérifie si nous avons déjà cet élément à faire geddy.db.todos.findOne (id: todo.id, function (err, doc) if (err) return callback (err, null);  // si nous avons déjà la tâche à faire, mettez-la à jour avec les nouvelles valeurs if (doc) geddy.db.todos.update (id: todo.id, cleanTodo, function (err, docs) return callback (todo.errors, todo);); // si nous n'avons pas déjà la tâche à faire, sauvegardez une nouvelle option todo.saved = true; geddy.db.todos.save (todo, function ( err, docs) return callback (err, docs););); 

Ne soyez pas trop découragé par celui-ci; nous avons commencé par le plus complexe en premier. Rappelez-vous que notre enregistrer méthode doit tenir compte à la fois de nouveaux faires et mise à jour vieux faires. Voyons donc ce code étape par étape.

Nous utilisons le même code de rappel que précédemment. Si aucun rappel ne nous est transmis, utilisez simplement une fonction vide..

Ensuite, nous désinfectons notre faire article. Nous devons le faire parce que notre faire objet a des méthodes JavaScript dessus (comme enregistrer), et Mongo n'aime pas quand vous lui passez des objets avec des méthodes. Nous créons donc simplement un nouvel objet avec uniquement les propriétés qui nous intéressent.

Ensuite, nous vérifions si le faire est valable. Si ce n'est pas le cas, nous appelons le rappel avec les erreurs de validation. Si c'est le cas, nous continuons.

Au cas où nous avons déjà cette faire élément dans la base de données, nous vérifions la base de données pour voir si un faire existe. C’est là que nous commençons à utiliser le mongodb-wrapper module. Cela nous donne une API propre pour travailler avec notre base de données. Ici, nous utilisons le db.todos.findOne () méthode pour trouver un seul document qui satisfait notre requête. Notre requête est un simple objet js - nous recherchons un document dont identifiant est le même que notre faires identifiant. Si nous en trouvons un et qu’il n’ya pas d’erreur, nous utilisons le db.todos.update () méthode pour mettre à jour le document avec les nouvelles données. Si nous n'en trouvons pas, nous utilisons le db.todos.save () méthode pour enregistrer un nouveau document avec le faire données de l'article.

Dans tous les cas, nous appelons un rappel lorsque nous avons terminé, les erreurs que nous avons reçues et les documents que la base de données nous a renvoyés lui étant transmis..

Modification de la méthode all

Regardez le tout méthode, il devrait ressembler à ceci:

this.all = fonction (rappel) rappel (null, geddy.todos); 

Faisons-le ressembler à ceci:

this.all = fonction (rappel) var todos = []; geddy.db.todos.find (). sort (status: -1, titre: 1). toArray (function (err, docs) // en cas d'erreur, retourne tôt if (err) callback ( err, null); // parcourez les documents et créez des modèles pour (var i dans les documents) todos.push (geddy.model.Todo.create (docs [i])) renvoyer un rappel (null, todos);); 

Beaucoup plus simple que le enregistrer méthode, vous ne pensez pas? Nous utilisons le db.todos.find () méthode pour obtenir tous les éléments du todos collection. Nous utilisons monogdb-wrapperapi à Trier les résultats par statut (en ordre alphabétique décroissant) et par Titre (par ordre alphabétique croissant). Ensuite, nous envoyons cela à un tableau, ce qui déclenche le démarrage de la requête. Une fois que nous avons récupéré nos données, nous vérifions s'il y a des erreurs. S'il y en a, nous appelons le rappel avec l'erreur. S'il n'y a pas d'erreurs nous continuons sur.

Ensuite, nous parcourons tous les docs (les documents que mongo nous a rendus), créer un nouveau faire des exemples de modèles pour chacun d’eux, et les pousser à un todos tableau. Lorsque nous avons terminé là-bas, nous appelons le rappel, en passant le todos.

Modification de la méthode de chargement

Jetez un coup d'œil à la méthode 'load', elle devrait ressembler à ceci:

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

Faisons-le ressembler à ceci:

this.load = function (id, callback) var todo; // recherche une tâche dans la base de données geddy.db.todos.findOne (id: id, fonction (err, doc) // en cas d'erreur, retourne tôt si (err) retour callback (err, null) ; // s'il y a un doc, créez un modèle avec celui-ci if (doc) todo = geddy.model.Todo.create (doc); return callback (null, todo);); ;

Celui-ci est encore plus simple. Nous utilisons le db.todos.findOne () méthode à nouveau. Cette fois, c’est tout ce que nous devons utiliser. Si nous avons une erreur, nous appelons le callback avec elle, sinon, nous continuons (vous voyez encore un motif ici?). Si nous avons un doc, nous créons une nouvelle instance du faire modèle et appeler le rappel avec elle. Voilà pour celui-là.

Modification de la méthode remove

Regardez le retirer méthode maintenant, il devrait ressembler à ceci:

this.remove = function (id, callback) if (type de callback! = 'fonction') callback = function () ;  pour (var i dans geddy.todos) if (geddy.todos [i] .id == id) geddy.todos.splice (i, 1); retourne le rappel (null);  retourne le rappel (message: "To Do not found"); ;

Faisons-le ressembler à ceci:

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

La méthode de suppression est encore plus courte que par le passé. Nous utilisons le db.todos.remove () méthode pour supprimer tous les documents avec le passé identifiant et appeler le rappel avec une erreur (le cas échéant).


Temps pour la magie

Allons tester notre application: CD dans le répertoire de votre projet et démarrez le serveur avec geddy. Créer un nouveau faire. Essayez de le modifier, faites échouer certaines validations et essayez de le supprimer. Tout fonctionne!


Conclusion

J'espère que vous avez apprécié l'apprentissage de Node.js, MongoDB et plus particulièrement de Geddy. Je suis sûr que vous avez maintenant un million d'idées sur ce que vous pourriez construire avec cela, et j'aimerais en entendre parler. Comme toujours, si vous avez des questions, laissez un commentaire ici ou ouvrez un problème sur github.