Commit 61078b2d authored by Kristian Freeman's avatar Kristian Freeman

Add schema exercise

parent 745846bb
......@@ -2,8 +2,7 @@ const MongoClient = require("mongodb").MongoClient;
const assert = require("assert");
const port = process.env.PORT || 27017;
const url = `mongodb://localhost:${port}`;
const dbName = "myproject";
const url = `mongodb://localhost:${port}/trainingproject`;
MongoClient.connect(
url,
......
const mongoose = require("mongoose");
const connect = require("./utils/connection");
const { User } = require("./models/User");
/*
* In this exercise, we'll define a few mongoose schemas,
* and utilize them to:
* 1. Connect to mongodb
* 2. Create a user with todos
* 3. Find the user in the database after it's been created
* 4. Log the user out
* 5. And close the mongodb connection
*
* To begin, go to ./models/User, and begin defining your
* User schema! You'll be directed back here when it's time to write
* the createUser function.
*
* Now that we're back in index.js, it's time to finish this exercise
* and actually use the models and schemas we've defined.
*
* Create a new function createUser - this is going to be an
* _asynchronous function_, so we should prefix the function with the
* async keyword:
*
* async function whateverFunc() {
* }
*
* This async function will allow us to use the powerful async/await
* functionality in Node - instead of relying heavily on Promise behavior
* (.then, .catch, etc), which leads to a lot of nested code and confusing
* readability issues, async and await will make our code a lot cleaner
* and easier to follow.
*
* The createUser function is going to do a couple things (and you could
* argue that some of them should be separate functions, but for now,
* we'll go with it):
*
* 1. Call the connect function, which has been imported from utils/connection.
* This function connects to the mongodb instance, and sets up a global
* connection inside of mongoose that we'll re-use throughout the function.
*
* 2. Drops the database, by calling mongoose.connection.dropDatabase. This is
* optional - if you don't add this line, there will be multiple instances
* of our user model inside of the database. If you do call this function,
* 2. Calls User.create, passing in an object with the data we want to provide
* to our user. The data we pass in will look something like this:
*
* {
* name: "Kristian",
* username: "signalnerve",
* todos: [
* { name: "Finish this exercise" },
* { name: "Get lunch" },
* { name: "Learn Express, MongoDB, and all the JS in the world" }
* ]
* }
*
* Pass in a name and username of your choice, and define at least 2 or 3
* todos of your own as well.
*
* Finally, prefix this function with "await". This means that the function will
* wait for this function to finish executing before continuing with the
* rest of the code. The format will look something like this:
*
* await myFunc();
*
* 3. Our code will now wait for the user to be created before continuing. Once
* the user is created, we should look the user back up, to confirm that
* it's actually been persisted in the database. To do this, call User.find,
* setting it to the variable user. Because this is an asynchronous operation,
* we need to prefix the User.find call with await!
*
* 4. With our user retrieved from the DB, let's simply console.log it out to see
* what the data looks like.
*
* 5. Finally, let's close the mongoose connection by calling
* mongoose.connection.close. If we were to kill this node process, or type
* Control-C, it's likely that the connection would close on its own. But we
* should be safe and ensure that once we're done working with MongoDB, we close
* the connection explicitly and not leave any hanging connections to the DB that
* we don't keep track of.
*
* 6. As a bonus trick, let's comment out all of the code surrounding dropping the
* database and creating a user, just leaving the User.find code. When we run
* this exercise again, we should make sure that the user is being persisted to
* the MongoDB database. If it does... congrats! We've created a database :)
*
*/
async function createUser() {}
createUser();
/*
* Similarly to the User file, we'll define another
* schema for todos in this file.
*
* One interesting aspect here is that todos will be
* _nested_ underneath users: a user _has_ many todos,
* and we won't really be creating a Todo model without
* it being attached to a user. Because of this, we'll
* just define a todoSchema, and export it to be used inside of
* the User model.
*
* Let's start by importing mongoose, similarly to how we did
* it in the User model file.
*
* Now define todoSchema, which is the value of calling
* new mongoose.Schema, passing in a single argument, the fields
* for our schema:
*
* - name is a string
* - notes is a string
* - created_at is an object, with a type of Date and default of
* Date.now
* - updated_at is an object, with a type of Date and default of
* Date.now
* - completed_at is an object, with a type of Date (and no default)
*
* With this schema defined, we're going to skip defining a Todo
* model itself! Again, the reason for this is that todos will live
* inside of the User model, and so we care exclusively about using
* the todoSchema inside of our userSchema.
*
* The one caveat here is that in a future design of this application,
* we may want to use the Todo model directly, for instance, if we
* need to lookup a Todo independent of a User. We'll examine that later:
* for now, simply export the todoSchema, using the same syntax that we
* used for exporting User in the previous file.
*
* Once you've done that, go back to models/User to finish the implementation
* of our models and schemas.
*
*/
/*
* A mongoose schema defines common functionality for
* querying and creating models in mongodb. Let's define a User
* schema!
*
* To begin, import the mongoose package, naming the variable
* "mongoose".
*
* We can now define our first schema. call new mongoose.Schema,
* passing a single object argument with our user fields. Fields
* are defined as key value pairs, like so:
*
* new mongoose.Schema({
* name: String
* // ...more fields
* })
*
* The user fields we should define are:
* - name, which is a String
* - username, which is a String
* - created_at, which is an object with two key value pairs:
* type, which is Date, and default, which is Date.now
* - updated_at, which is an object with two key value pairs:
* type, which is Date, and default, which is Date.now
*
* Once you've defined the User schema, we should actually
* instantiate the mongoose model. Do this by calling the function
* mongoose.model, passing in two arguments: the string "User"
* (the model name), and the userSchema. Set the value of this
* model to User.
*
* Before moving on to our next model, let's export User from this
* file. Set module.exports to an object, passing in a single key, User.
* The format will look like this:
*
* module.exports = { Thing }
*
* Now move on to models/Todo.js - we'll come back to this file soon!
*
* Once you've finished models/Todo.js, we need to use the todoSchema
* inside of our userSchema. Import todoSchema from ./Todo, using
* the named import format. Given a schema and source file Event, this
* would look something like:
*
* const { eventSchema } = require('./Event')
*
* Now we want to use the todosSchema inside of our userSchema. Add a new
* field todos, setting the value to an array with a single value, todoSchema:
*
* const userSchema = new mongoose.Schema({
* // ...
* events: [eventSchema],
* // ...
* });
*
* With this work completed, let's go back to index.js and finish the exercise.
*
*/
{
"name": "mongodb-schema",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"async": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz",
"integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==",
"requires": {
"lodash": "^4.17.10"
}
},
"bluebird": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
"integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA=="
},
"bson": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/bson/-/bson-1.1.0.tgz",
"integrity": "sha512-9Aeai9TacfNtWXOYarkFJRW2CWo+dRon+fuLZYJmvLV3+MiUp0bEI6IAZfXEIg7/Pl/7IWlLaDnhzTsD81etQA=="
},
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"requires": {
"ms": "2.0.0"
}
},
"kareem": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.0.tgz",
"integrity": "sha512-6hHxsp9e6zQU8nXsP+02HGWXwTkOEw6IROhF2ZA28cYbUk4eJ6QbtZvdqZOdD9YPKghG3apk5eOCvs+tLl3lRg=="
},
"lodash": {
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
},
"lodash.get": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
"integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
},
"memory-pager": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.1.0.tgz",
"integrity": "sha512-Mf9OHV/Y7h6YWDxTzX/b4ZZ4oh9NSXblQL8dtPCOomOtZciEHxePR78+uHFLLlsk01A6jVHhHsQZZ/WcIPpnzg==",
"optional": true
},
"mongodb": {
"version": "3.1.8",
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.1.8.tgz",
"integrity": "sha512-yNKwYxQ6m00NV6+pMoWoheFTHSQVv1KkSrfOhRDYMILGWDYtUtQRqHrFqU75rmPIY8hMozVft8zdC4KYMWaM3Q==",
"requires": {
"mongodb-core": "3.1.7",
"safe-buffer": "^5.1.2"
}
},
"mongodb-core": {
"version": "3.1.7",
"resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.1.7.tgz",
"integrity": "sha512-YffpSrLmgFNmrvkGx+yX00KyBNk64C0BalfEn6vHHkXtcMUGXw8nxrMmhq5eXPLLlYeBpD/CsgNxE2Chf0o4zQ==",
"requires": {
"bson": "^1.1.0",
"require_optional": "^1.0.1",
"safe-buffer": "^5.1.2",
"saslprep": "^1.0.0"
}
},
"mongoose": {
"version": "5.3.11",
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.3.11.tgz",
"integrity": "sha512-LrsatxtUfZAerAxyFiaw/8T8M4T9Ff9+6wFkJwfTVDz9skX+HVOs70QOzTDawz0k0Q0I6qt9xv/ZYQi2Paykgw==",
"requires": {
"async": "2.6.1",
"bson": "~1.1.0",
"kareem": "2.3.0",
"lodash.get": "4.4.2",
"mongodb": "3.1.8",
"mongodb-core": "3.1.7",
"mongoose-legacy-pluralize": "1.0.2",
"mpath": "0.5.1",
"mquery": "3.2.0",
"ms": "2.0.0",
"regexp-clone": "0.0.1",
"safe-buffer": "5.1.2",
"sliced": "1.0.1"
}
},
"mongoose-legacy-pluralize": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz",
"integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ=="
},
"mpath": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/mpath/-/mpath-0.5.1.tgz",
"integrity": "sha512-H8OVQ+QEz82sch4wbODFOz+3YQ61FYz/z3eJ5pIdbMEaUzDqA268Wd+Vt4Paw9TJfvDgVKaayC0gBzMIw2jhsg=="
},
"mquery": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.0.tgz",
"integrity": "sha512-qPJcdK/yqcbQiKoemAt62Y0BAc0fTEKo1IThodBD+O5meQRJT/2HSe5QpBNwaa4CjskoGrYWsEyjkqgiE0qjhg==",
"requires": {
"bluebird": "3.5.1",
"debug": "3.1.0",
"regexp-clone": "0.0.1",
"safe-buffer": "5.1.2",
"sliced": "1.0.1"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
"regexp-clone": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-0.0.1.tgz",
"integrity": "sha1-p8LgmJH9vzj7sQ03b7cwA+aKxYk="
},
"require_optional": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz",
"integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==",
"requires": {
"resolve-from": "^2.0.0",
"semver": "^5.1.0"
}
},
"resolve-from": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz",
"integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c="
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"saslprep": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.2.tgz",
"integrity": "sha512-4cDsYuAjXssUSjxHKRe4DTZC0agDwsCqcMqtJAQPzC74nJ7LfAJflAtC1Zed5hMzEQKj82d3tuzqdGNRsLJ4Gw==",
"optional": true,
"requires": {
"sparse-bitfield": "^3.0.3"
}
},
"semver": {
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
"integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg=="
},
"sliced": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz",
"integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E="
},
"sparse-bitfield": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
"integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=",
"optional": true,
"requires": {
"memory-pager": "^1.0.2"
}
}
}
}
{
"name": "mongodb-schema",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"mongoose": "^5.3.11"
}
}
const mongoose = require("mongoose");
const port = process.env.PORT || 27017;
const url = `mongodb://localhost:${port}/trainingproject`;
const connect = () =>
mongoose.connect(
url,
{ useNewUrlParser: true }
);
module.exports = connect;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment