{"componentChunkName":"component---src-templates-legacy-tutorial-page-js","path":"/oa/tutorials/make-tweets/index-events/","result":{"pageContext":{"tutorial":{"id":"T0E6OlR1dG9yaWFsLTE4Mw==","slug":"make-tweets","title":"Make Parties","previewText":"Create your very own event planning social network and learn Node.js, Express.js, and SQL\nin the process.\n","heroImagePath":"https://raw.githubusercontent.com/MakeSchool-Tutorials/Make-Parties/master/cover.jpg","heroImageFile":{"childImageSharp":{"gatsbyImageData":{"layout":"constrained","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAMEAf/EABYBAQEBAAAAAAAAAAAAAAAAAAIBAP/aAAwDAQACEAMQAAABzWvYnGsT0hzgu//EAB0QAAICAQUAAAAAAAAAAAAAAAACAREQEhMhMUH/2gAIAQEAAQUC7jxks21NKkqRyVGP/8QAFxEAAwEAAAAAAAAAAAAAAAAAAAEREP/aAAgBAwEBPwGMu//EABcRAAMBAAAAAAAAAAAAAAAAAAABERD/2gAIAQIBAT8BhHv/xAAYEAACAwAAAAAAAAAAAAAAAAAQIQAgQf/aAAgBAQAGPwIKaFT/xAAcEAEAAgMAAwAAAAAAAAAAAAABABEhMUEQYZH/2gAIAQEAAT8hpQQzC6a+EZDWqhjy4BWNR71T3Nl8lHPH/9oADAMBAAIAAwAAABArx73/xAAWEQEBAQAAAAAAAAAAAAAAAAABABD/2gAIAQMBAT8QgEZ//8QAGBEAAgMAAAAAAAAAAAAAAAAAAAEQEUH/2gAIAQIBAT8Qtogcf//EABsQAQEBAQADAQAAAAAAAAAAAAERIQAxUWGh/9oACAEBAAE/EMRflAOy2lFPR0HU/GV4ApUrMn5Owwogrc5xmKXSfO1GBSGdkh3OswCHzv/Z"},"images":{"fallback":{"src":"/mediabook/static/49d0f35cb3ed71a753f71fb34c762574/dd515/cover.jpg","srcSet":"/mediabook/static/49d0f35cb3ed71a753f71fb34c762574/6ac16/cover.jpg 50w,\n/mediabook/static/49d0f35cb3ed71a753f71fb34c762574/e07e1/cover.jpg 100w,\n/mediabook/static/49d0f35cb3ed71a753f71fb34c762574/dd515/cover.jpg 200w,\n/mediabook/static/49d0f35cb3ed71a753f71fb34c762574/47930/cover.jpg 400w","sizes":"(min-width: 200px) 200px, 100vw"},"sources":[{"srcSet":"/mediabook/static/49d0f35cb3ed71a753f71fb34c762574/b79cb/cover.avif 50w,\n/mediabook/static/49d0f35cb3ed71a753f71fb34c762574/6d0de/cover.avif 100w,\n/mediabook/static/49d0f35cb3ed71a753f71fb34c762574/f2685/cover.avif 200w,\n/mediabook/static/49d0f35cb3ed71a753f71fb34c762574/4ff31/cover.avif 400w","type":"image/avif","sizes":"(min-width: 200px) 200px, 100vw"},{"srcSet":"/mediabook/static/49d0f35cb3ed71a753f71fb34c762574/dbc4a/cover.webp 50w,\n/mediabook/static/49d0f35cb3ed71a753f71fb34c762574/d8057/cover.webp 100w,\n/mediabook/static/49d0f35cb3ed71a753f71fb34c762574/2e34e/cover.webp 200w,\n/mediabook/static/49d0f35cb3ed71a753f71fb34c762574/416c3/cover.webp 400w","type":"image/webp","sizes":"(min-width: 200px) 200px, 100vw"}]},"width":200,"height":200}}},"pages":{"nodes":[{"id":"T0E6OlBhZ2UtMTUxOQ==","title":"Making A Plan & Starting an Express.js Project","slug":"start-an-express-project-z9Y=","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tODIzMw==","title":"Making A Plan & Starting an Express.js Project","htmlContent":"<p>You might know the website <a href=\"https://eventbrite.com\" target=\"_blank\">EventBrite</a>. It is a site where people can find great events to attend. In this tutorial you are going to build <strong>Make Parties</strong> - your very own event website.</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P00-Start-An-Express-Project/assets/finished-example.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P00-Start-An-Express-Project/assets/finished-example.png\" alt=\"finished example\" title=\"\">\n        </a></p>"},{"id":"T0E6OlNlY3Rpb24tODIzNA==","title":"Prerequisites","htmlContent":"<p>Before starting this tutorial you should be familiar with the following topics:</p><ul>\n<li>HTML/CSS &amp; Bootstrap</li>\n<li>JavaScript Fundamentals</li>\n</ul>"},{"id":"T0E6OlNlY3Rpb24tODIzNQ==","title":"Learning Outcomes","htmlContent":"<p>By the end of this tutorial, you should be able to...</p><ol>\n<li>Build a web app using Node.js and Handlebars</li>\n<li>Implement the internet-wide paradigms of RESTful and Resourceful routing</li>\n<li>Create, Read, Update, and Delete (CRUD) a single <code>Event</code> resource</li>\n<li>Create and delete an additional resource (<code>Rsvp</code>), and associate it to another resource</li>\n<li>Use a SQL document-based database with an Object Document Mapper (Sequelize).</li>\n</ol>"},{"id":"T0E6OlNlY3Rpb24tODIzNg==","title":"How to Plan a Coding Project: User Stories","htmlContent":"<p>Before we get started, let's make a plan for what <strong>User Stories</strong> we're going to build. Then we'll jump in and start Express.js app and add a templating engine.</p><p>Software development these days is organized into <strong>Agile Sprints</strong> that are usually two weeks long. You'll notice evidence of this if you ever update your apps and read the update text. Sometimes it just says:</p><pre><span class=\"nx\">We</span> <span class=\"nx\">ship</span> <span class=\"nx\">a</span> <span class=\"k\">new</span> <span class=\"nx\">version</span> <span class=\"nx\">every</span> <span class=\"nx\">two</span> <span class=\"nx\">weeks</span><span class=\"p\">...</span>\n</pre><p>That's because they are organizing their engineering in this standard agile way.</p><p>During each sprint developers pick a few <strong>User Stories</strong> to build, test, and ship to production. A <strong>User Story</strong> is one chunk of functionality. Engineers use the term <strong>User Story</strong> instead of \"feature\" to emphasize the user's experience in their design, development and testing. This emphasis on the user is called <strong>User Centered Development</strong>. Whenever you build anything on a team or by yourself, always use a <strong>Backlog</strong> of <strong>User Stories</strong> to organize and prioritize what you will build and when.</p><p>It is a good habit to build applications one resource at a time, adding all the <strong>Resourceful Routes</strong> for each resource before moving to the next.</p><p>So the user stories we can have for this event app will be as follows:</p><ol>\n<li>Users can view all events (index)</li>\n<li>Users can create a event (new/create)</li>\n<li>Users can view one event (show)</li>\n<li>Users can edit a event (edit/update)</li>\n<li>Users can delete a event (destroy)</li>\n</ol><p>Once we have this single Event resource build, we can move onto making an associated RSVP resource.</p><ol>\n<li>Users can rsvp to events (/rsvps/create, /rsvps/new)</li>\n<li>Users can cancel their rsvp (/rsvps/destroy)</li>\n</ol><p>As we finish our user stories we'll be committing to GitHub &#128025;.</p>"},{"id":"T0E6OlNlY3Rpb24tODIzNw==","title":"Getting Started - Cloud9","htmlContent":"<p><strong>(Ignore this section if you are installing the development environment on your own computer)</strong></p><p>Now that we have some user stories, let's initialize an Express.js project so we can start on the first user story in the next chapter of this tutorial.</p><div class=\"action\">\n<p></p>\n\n<p>If you are using Cloud9</p>\n\n<ol>\n<li>Select \"Create a New Workspace\"</li>\n<li>Name your project 'make-parties'</li>\n<li>At the bottom select a HTML5 template</li>\n<li>Delete the hello-world file.</li>\n<li>You are good to go!</li>\n</ol>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODIzOA==","title":"Getting Started - Setting up your Computer","htmlContent":"<p><strong>(Ignore this section if you are using Cloud9)</strong></p><p>For reference for the rest of this chapter you can look at <a href=\"https://expressjs.com/en/starter/installing.html\" target=\"_blank\">ExpressJS's Getting Started</a> docs for help with getting started.</p><div class=\"info\">\n<p>\nWhenever you see the <code>$</code> in a command, that means it should be called in your computer's terminal. Remember: Don't include the <code>$</code> in your command.</p>\n</div><p>First things first, we need a tool to help us install things like packages and libraries. <a href=\"(https://brew.sh/)\" target=\"_blank\">Homebrew</a> is Mac's package manager, so let's install that first!</p><div class=\"action\">\n<p></p>\n\n<p>Open your computer's terminal and then install Homebrew:</p>\n<pre>$ /usr/bin/ruby -e <span class=\"s2\">\"</span><span class=\"k\">$(</span>curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install<span class=\"k\">)</span><span class=\"s2\">\"</span>\n</pre>\n</div><p>Cool, now let's get our environment set up. <code>npm</code>, NodeJS's package manager, is installed automatically when you install node, so we'll be able to install node modules from our command line once we install node.</p><div class=\"action\">\n<p></p>\n\n<p>install NodeJS:</p>\n<pre>$ brew install node\n</pre>\n</div><p>Now that we have Node installed (and therefore have <code>npm</code>), Let's set up our working directory where we'll build our project.</p><div class=\"action\">\n<p></p>\n\n<p>Make a new directory called <code>make-parties</code>, then navigate into that directory</p>\n<pre>$ mkdir make-parties\n$ <span class=\"nb\">cd</span> make-parties\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODIzOQ==","title":"Starting a Node.js & Express.js Project","htmlContent":"<p>Use the command <code>npm init</code> (\"npm initialize\") to kick off a node project. This command will prompt you to define the configuration options that will be recorded in a file called <code>package.json</code>. <em>Just hit enter for each option to select the default choice.</em></p><div class=\"action\">\n<p></p>\n\n<p>Run <code>npm init</code> to kick off the project:</p>\n<pre>$ npm init\n</pre>\n</div><p>Now if you open your project in Atom, you'll see the <code>package.json</code> which records the npm configuration you define upon initialization of the project.</p>"},{"id":"T0E6OlNlY3Rpb24tODI0MA==","title":"Adding Express.js","htmlContent":"<p>Now we need to add Express.js.</p><div class=\"info\">\n<p>\nExpress.js is a web framework. Node.js is your server. Express is a structure that makes it easy to use node to handle web requests through HTTP, and then to add other libraries called <strong>middleware</strong> to do other common website patterns like render HTML, accept form data, serve images and other static assets, and everything else websites can do. With Express as a base, you can build literally anything in the internet from Google to Uber.</p>\n</div><p>Lets start by just getting Express to say \"Hello World!\". Then we'll add a template engine called <a href=\"https://handlebarsjs.com/\" target=\"_blank\">Handlebars</a> so Express can render HTML.</p><p>Express.js is template engine-agnostic, meaning we could use all sorts of templating engines. We're going to use Handlebars so we get two key features:</p><ol>\n<li>A layout template, which will make organizing our templates easier</li>\n<li>We'll actually write HTML. Some templating engines you write in a custom version of html to simplify it but we want to practice writing real HTML.</li>\n</ol><p>Our main file of our whole application we'll call <code>app.js</code></p><div class=\"action\">\n<p>\nFirst install Express.js and then create the main file using the <code>touch</code> command.</p>\n<pre>$ npm install express\n$ touch app.js\n</pre>\n</div><p>Now your project should have two files and a folder: <code>app.js</code>, <code>package.json</code>, and <code>node_modules</code>.</p><div class=\"action\">\n<p></p>\n\n<p><strong>(If your on Cloud9 ignore this step)</strong>\nNow if you are on your computer, open your project's code base using the Atom text editor by typing:</p>\n<pre>$ atom .\n</pre>\n</div><p>Let's add some standard Express.js code to <code>app.js</code> to show a hello world:</p><div class=\"action\">\n<p></p>\n\n<p>Add the following to <code>app.js</code>:</p>\n<pre><span class=\"c1\">// Initialize express</span>\n<span class=\"kr\">const</span> <span class=\"nx\">express</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'express'</span><span class=\"p\">)</span>\n<span class=\"kr\">const</span> <span class=\"nx\">app</span> <span class=\"o\">=</span> <span class=\"nx\">express</span><span class=\"p\">()</span>\n\n<span class=\"c1\">// Tell our app to send the \"hello world\" message to our home page</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">send</span><span class=\"p\">(</span><span class=\"s1\">'Hello World!'</span><span class=\"p\">)</span>\n<span class=\"p\">})</span>\n\n<span class=\"c1\">// Choose a port to listen on</span>\n<span class=\"kr\">const</span> <span class=\"nx\">port</span> <span class=\"o\">=</span> <span class=\"nx\">process</span><span class=\"p\">.</span><span class=\"nx\">env</span><span class=\"p\">.</span><span class=\"nx\">PORT</span> <span class=\"o\">||</span> <span class=\"mi\">3000</span><span class=\"p\">;</span>\n\n<span class=\"c1\">// Tell the app what port to listen on</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">listen</span><span class=\"p\">(</span><span class=\"nx\">port</span><span class=\"p\">,</span> <span class=\"p\">()</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"s1\">'App listening on port 3000!'</span><span class=\"p\">)</span>\n<span class=\"p\">})</span>\n</pre>\n</div><p>Now run your project!</p><div class=\"action\">\n<p></p>\n\n<p>Run the following command to get your project up and running:</p>\n<pre>$ node app.js\n</pre>\n<p><strong>If you are on Cloud9:</strong> select Preview &gt; Preview Running Application to open a browser panel.</p>\n\n<p><strong>If you are on your computer:</strong> point your browser to <code>http://localhost:3000</code>.</p>\n</div><p>Remember that we still haven't added a template engine yet. We are just sending text back to the browser, but you should see an empty page except for the the text \"Hello World!\"</p>"},{"id":"T0E6OlNlY3Rpb24tODI0MQ==","title":"Install nodemon and launch your server","htmlContent":"<p>Let's install <code>nodemon</code> if you haven't already. <a href=\"https://nodemon.io/\" target=\"_blank\">Nodemon</a> just helps us by restarting our server every time we change our code.</p><div class=\"action\">\n<p></p>\n\n<p>Install and run <code>nodemon</code>:</p>\n<pre>$ npm install nodemon -g\n$ nodemon app.js\n</pre>\n</div><p>In your terminal, you should see <code>App listening on port 3000!</code> as an output. How did this get here?</p><p>From the <code>console.log</code> inside of <code>app.listen(3000 ...)</code>! Make sure to refresh your browser (if you're on <code>localhost</code>) to make sure that the text is still displaying and everything is working properly.</p>"},{"id":"T0E6OlNlY3Rpb24tODI0Mg==","title":"Add Handlebars.js as a Templating Engine","htmlContent":"<p>Now, we are going to need to render HTML for our project, so we have to add a <strong>Templating Engine</strong> if we want extend Express.js to use HTML.</p><p>Let's add our templating engine Handlebars.js so our Express.js server can render templates. This is called <em>server-side HTML templates</em>. </p><p>We're also going to add a package called <code>allow-prototype-access</code> to avoid a common error we will run into later.</p><div class=\"action\">\n<p>\nInstall Handlebars.js to your project using the <code>express-handlebars</code> node module.</p>\n<pre>$ npm install express-handlebars @handlebars/allow-prototype-access\n</pre>\n</div><p>Now that we've installed the package, we must require it or <strong>initialize</strong> it in your app:</p><div class=\"action\">\n<p></p>\n\n<p>Update <code>app.js</code> to include the following after the <code>const app = express()</code> line:</p>\n<pre><span class=\"c1\">// require handlebars</span>\n<span class=\"kr\">const</span> <span class=\"nx\">exphbs</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'express-handlebars'</span><span class=\"p\">);</span>\n<span class=\"kr\">const</span> <span class=\"nx\">Handlebars</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'handlebars'</span><span class=\"p\">)</span>\n<span class=\"kr\">const</span> <span class=\"p\">{</span><span class=\"nx\">allowInsecurePrototypeAccess</span><span class=\"p\">}</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'@handlebars/allow-prototype-access'</span><span class=\"p\">)</span>\n\n<span class=\"c1\">// Use \"main\" as our default layout</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">engine</span><span class=\"p\">(</span><span class=\"s1\">'handlebars'</span><span class=\"p\">,</span> <span class=\"nx\">exphbs</span><span class=\"p\">({</span> <span class=\"nx\">defaultLayout</span><span class=\"o\">:</span> <span class=\"s1\">'main'</span><span class=\"p\">,</span> <span class=\"nx\">handlebars</span><span class=\"o\">:</span> <span class=\"nx\">allowInsecurePrototypeAccess</span><span class=\"p\">(</span><span class=\"nx\">Handlebars</span><span class=\"p\">)</span> <span class=\"p\">}));</span>\n<span class=\"c1\">// Use handlebars to render</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">set</span><span class=\"p\">(</span><span class=\"s1\">'view engine'</span><span class=\"p\">,</span> <span class=\"s1\">'handlebars'</span><span class=\"p\">);</span>\n</pre>\n</div><p>Now let's render a handlebars home page!</p><div class=\"action\">\n<p>\nExtend your <strong>root route</strong> ('/') to render <code>home.handlebars</code>.</p>\n<pre><span class=\"c1\">// app.js</span>\n\n<span class=\"c1\">// Render the \"home\" layout for the main page and send the following msg</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'home'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">msg</span><span class=\"o\">:</span> <span class=\"s1\">'Handlebars are Cool!'</span> <span class=\"p\">});</span>\n<span class=\"p\">})</span>\n</pre>\n</div><p>Refresh your browser now and read the error you get carefully. This error tells us that our application can't find a <code>home.handlebars</code> template yet (because we haven't made it!).</p><div class=\"info\">\n<p>\nIt is useful to try to predict what error you might get as you are coding, and see if you get the error you expected. Errors can be a great way to check your work as you go and not go too far before checking your work.</p>\n</div><!-- --><div class=\"action\">\n<p>\nCreate the <code>views</code>, <code>layouts</code> folders and <code>main.handlebars</code> and file.\n<code>bash\n$ mkdir views\n$ mkdir views/layouts\n$ touch views/layouts/main.handlebars\n</code></p>\n</div><p>So now we have our <strong>views</strong> folder setup with a <strong>layout template</strong> called <code>main</code>. Great!</p><p>Now we'll add some boilerplate code to the <code>main.handlebars</code> layout template. Remember that we used Handlebars because it has a <strong>Layout Template</strong>. A <strong>layout template</strong> is a super-template that all other templates will inherit from. This is like a \"super-template\" that all other templates are embedded in. Having a layout template means we can put things that go on <em>every</em> page in just one file of code. These templates will be threaded in right at the <code>{{{body}}}</code>.</p><div class=\"action\">\n<p></p>\n\n<p>Add the following to <code>views/layouts/main.handlebars</code></p>\n<pre><span class=\"c\">&lt;!-- views/layouts/main.handlebars --&gt;</span>\n<span class=\"cp\">&lt;!doctype html&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">html</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">head</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">meta</span> <span class=\"na\">charset</span><span class=\"o\">=</span><span class=\"s\">\"utf-8\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">title</span><span class=\"p\">&gt;</span>Make Parties<span class=\"p\">&lt;/</span><span class=\"nt\">title</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">head</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">body</span><span class=\"p\">&gt;</span>\n\n  {{{body}}}\n\n<span class=\"p\">&lt;/</span><span class=\"nt\">body</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">html</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>Now we can make our <code>views/home.handlebars</code> template (a new file in our <code>views</code> director). This template will use <code>main.handlebars</code> as a boilerplate, but what we write in <code>home.handlebars</code> will render in the <code>{{{body}}}</code> portion of <code>main.handlebars</code>:</p><div class=\"action\">\n<p></p>\n\n<p>Create the <code>views/home.handlebars</code> file and then add the following to it:</p>\n<pre><span class=\"c\">&lt;!-- home.handlebars --&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>{{msg}}<span class=\"p\">&lt;/</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODI0Mw==","title":"Product So far","htmlContent":"<p>Now when you visit <code>localhost:3000</code> you should now see \"Handlebars are Cool!\" inside an <code>h1</code> tag:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P00-Start-An-Express-Project/assets/handlebars-are-cool.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P00-Start-An-Express-Project/assets/handlebars-are-cool.png\" alt=\"handlebars are cool\" title=\"\">\n        </a></p>"},{"id":"T0E6OlNlY3Rpb24tODI0NA==","title":"Initialize, Commit, and Push","htmlContent":"<p>Now that you have a basic initialized Express.js project, let's commit to github.</p><pre>$ git init\n$ git add .\n$ git commit -m <span class=\"s1\">'init'</span>\n</pre><p>Now go to github and create a public repository called <code>make-parties</code>, and now associate it as a remote for your local git project and then push to it.</p><pre>$ git remote add origin GITHUB-REPO-URL\n$ git push origin master -u\n</pre><p>We'll be doing this at the end of every chapter to make sure we're saving our progress as we go along!</p>"}]},"next":{"id":"T0E6OlBhZ2UtMTUyMA==","slug":"index-events","title":"See All Events"},"previous":{"id":"T0E6OlBhZ2UtMTUyMA==","slug":"index-events","title":"See All Events"}},{"id":"T0E6OlBhZ2UtMTUyMA==","title":"See All Events","slug":"index-events","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tODI0NQ==","title":"See All Events","htmlContent":"<p>Following our <strong>User Stories</strong> we are going to define a single <strong>Resource</strong> in this app called an <code>Event</code>.</p><ol>\n<li><strong>Users can view all events (index)</strong></li>\n<li>Users can create a event (new/create)</li>\n<li>Users can view one event (show)</li>\n<li>Users can edit a event (edit/update)</li>\n<li>Users can delete a event (destroy)</li>\n<li>Users can rsvp to events (/rsvps/create, /rsvps/new)</li>\n<li>Users can cancel their rsvp (/rsvps/destroy)</li>\n</ol><p>A <strong>Resource</strong> is an abstract object that we use to organize data, code, and the features of our app. For example, in a <code>User</code> resource we can keep track of logging in and out, email and passwords, and people's birthdays. In a blog, we might have an <code>Article</code> or <code>Post</code> resource where we would track the titles and bodies of articles and keep track of the code for publishing and sharing them.</p><p>Resources can also be related to each other. For example, articles may have comments; a building resource might have floors, and the floors may have units; a user might have friends (like in Facebook).</p><p>All resources have a few actions in common that are called <strong>Resourceful Routes</strong>. Memorize this table of routes:</p><table>\n<thead>\n<tr>\n<th>URL</th>\n<th>HTTP Verb</th>\n<th>Action</th>\n<th>What it Does</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>/events</td>\n<td>GET</td>\n<td>index</td>\n<td>See all events</td>\n</tr>\n<tr>\n<td>/events/new</td>\n<td>GET</td>\n<td>new</td>\n<td>See new event form</td>\n</tr>\n<tr>\n<td>/events</td>\n<td>POST</td>\n<td>create</td>\n<td>Create a new event</td>\n</tr>\n<tr>\n<td>/events/:id</td>\n<td>GET</td>\n<td>show</td>\n<td>See one event</td>\n</tr>\n<tr>\n<td>/events/:id/edit</td>\n<td>GET</td>\n<td>edit</td>\n<td>See an edit event form</td>\n</tr>\n<tr>\n<td>/events/:id</td>\n<td>PATCH/PUT</td>\n<td>update</td>\n<td>Update a event</td>\n</tr>\n<tr>\n<td>/events/:id</td>\n<td>DELETE</td>\n<td>destroy</td>\n<td>Delete a event</td>\n</tr>\n</tbody>\n</table><p>We're going to start with the <code>index</code> action and then <code>show</code>, and then we'll look at the <code>create</code>, <code>edit</code>, <code>update</code>, and <code>delete</code>.</p>"},{"id":"T0E6OlNlY3Rpb24tODI0Ng==","title":"Adding an '/events' Route","htmlContent":"<p>Let's make a route to <code>/events</code> for the index action where we can see all the events that we've created. Eventually this will be on our root route, but we can start making it its own separate path.</p><div class=\"action\">\n<p></p>\n\n<p>Add the following below the <code>app.get('/'...)</code> call in <code>app.js</code>:</p>\n<pre><span class=\"c1\">// OUR MOCK ARRAY OF PROJECTS</span>\n<span class=\"kd\">var</span> <span class=\"nx\">events</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n  <span class=\"p\">{</span> <span class=\"nx\">title</span><span class=\"o\">:</span> <span class=\"s2\">\"I am your first event\"</span><span class=\"p\">,</span> <span class=\"nx\">desc</span><span class=\"o\">:</span> <span class=\"s2\">\"A great event that is super fun to look at and good\"</span><span class=\"p\">,</span> <span class=\"nx\">imgUrl</span><span class=\"o\">:</span> <span class=\"s2\">\"https://img.purch.com/w/660/aHR0cDovL3d3dy5saXZlc2NpZW5jZS5jb20vaW1hZ2VzL2kvMDAwLzA4OC85MTEvb3JpZ2luYWwvZ29sZGVuLXJldHJpZXZlci1wdXBweS5qcGVn\"</span> <span class=\"p\">},</span>\n  <span class=\"p\">{</span> <span class=\"nx\">title</span><span class=\"o\">:</span> <span class=\"s2\">\"I am your second event\"</span><span class=\"p\">,</span> <span class=\"nx\">desc</span><span class=\"o\">:</span> <span class=\"s2\">\"A great event that is super fun to look at and good\"</span><span class=\"p\">,</span> <span class=\"nx\">imgUrl</span><span class=\"o\">:</span> <span class=\"s2\">\"https://img.purch.com/w/660/aHR0cDovL3d3dy5saXZlc2NpZW5jZS5jb20vaW1hZ2VzL2kvMDAwLzA4OC85MTEvb3JpZ2luYWwvZ29sZGVuLXJldHJpZXZlci1wdXBweS5qcGVn\"</span> <span class=\"p\">},</span>\n  <span class=\"p\">{</span> <span class=\"nx\">title</span><span class=\"o\">:</span> <span class=\"s2\">\"I am your third event\"</span><span class=\"p\">,</span> <span class=\"nx\">desc</span><span class=\"o\">:</span> <span class=\"s2\">\"A great event that is super fun to look at and good\"</span><span class=\"p\">,</span> <span class=\"nx\">imgUrl</span><span class=\"o\">:</span> <span class=\"s2\">\"https://img.purch.com/w/660/aHR0cDovL3d3dy5saXZlc2NpZW5jZS5jb20vaW1hZ2VzL2kvMDAwLzA4OC85MTEvb3JpZ2luYWwvZ29sZGVuLXJldHJpZXZlci1wdXBweS5qcGVn\"</span> <span class=\"p\">}</span>\n<span class=\"p\">]</span>\n\n<span class=\"c1\">// INDEX</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/events'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'events-index'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">events</span><span class=\"o\">:</span> <span class=\"nx\">events</span> <span class=\"p\">});</span>\n<span class=\"p\">})</span>\n</pre>\n</div><p>Notice how we are making a mock array of events, and sending that in as an object into the template <code>{ events: events }</code>. So the variable <code>events</code> will be available in our template!</p>"},{"id":"T0E6OlNlY3Rpb24tODI0Nw==","title":"Errors are Your Friends!","htmlContent":"<div class=\"action\">\n<p></p>\n\n<p>Send your browser to your <code>/events</code> path by going to <code>http://localhost:3000/events</code>. What do you see?</p>\n</div><p>An error!</p><p><strong>That's ok! Errors are our friends</strong>.</p><p>What does the error say? I bet it says something like \"I can't find the template 'events-index'\". That makes sense because we haven't made it yet! It's ok to complete coding tasks that throw a predictable error, and then use that error like a sign post.</p><div class=\"info\">\n<p>\nErrors often tell you the next step you need to take. In this case the error is telling you that the template does not exist. Let's make it!</p>\n</div><p>So to fix this error, let's add the template <code>views/events-index.handlebars</code>. We're going to use the Handlebars.js <code>{{#each}}</code> iterator to loop over our array of events and display each one's title.</p><div class=\"action\">\n<p></p>\n\n<p>Add <code>views/events-index.handlebars</code> to your project, and then put the following code into it:</p>\n<pre><span class=\"c\">&lt;!-- events-index --&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>Events<span class=\"p\">&lt;/</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>\n{{#each events}}\n  <span class=\"p\">&lt;</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>{{this.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">img</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"img-fluid\"</span> <span class=\"na\">src</span><span class=\"o\">=</span><span class=\"s\">\"{{this.imgUrl}}\"</span> <span class=\"na\">alt</span><span class=\"o\">=</span><span class=\"s\">\"Card image cap\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>{{this.description}}<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n{{/each}}\n</pre>\n</div><p>If you refresh <code>localhost:3000/events</code> now what do you see?</p><div class=\"solution\">\n<p>\nYou should see the mock events we wrote into code. Can you add to them or change them?</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODI0OA==","title":"Setting the Root Route - '/'","htmlContent":"<p>Let's update the <code>/events</code> route to be our root route. Just change the path from <code>/events</code> to <code>/</code> and delete or comment out the hello world root route we made before.</p><div class=\"action\">\n<p></p>\n\n<p>Update the call to <code>app.get('/')</code> to render <code>events-index</code> in <code>app.js</code>:</p>\n<pre><span class=\"c1\">// INDEX</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'events-index'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">events</span><span class=\"o\">:</span> <span class=\"nx\">events</span> <span class=\"p\">});</span>\n<span class=\"p\">})</span>\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODI0OQ==","title":"Product So Far","htmlContent":"<p>Now navigate to <code>localhost:3000</code>, and make sure you see those puppies!</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P01-Index-Events/assets/puppies.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P01-Index-Events/assets/puppies.png\" alt=\"puppies\" title=\"\">\n        </a></p>"},{"id":"T0E6OlNlY3Rpb24tODI1MA==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can see all mock events'</span>\n$ git push\n</pre>"},{"id":"T0E6OlNlY3Rpb24tODI1MQ==","title":"Stretch Challenge","htmlContent":"<p>Still hankering for more? Use these <strong>Stretch Challenge</strong> sections to implement additional functionality to your project. Note that you will never <em>need</em> to implement these in order to finish the tutorial, but if you want extra practice, or want to try out some advanced functionality, then this is for you!</p><div class=\"challenge\">\n<p></p>\n\n<p>Can you make changes to your <code>events</code> array in <code>app.js</code> and see it reflected in your <code>events-index</code> template?</p>\n</div>"}]},"next":{"id":"T0E6OlBhZ2UtMTUyMQ==","slug":"adding-bootstrap-iFg=","title":"Styling with Bootstrap"},"previous":{"id":"T0E6OlBhZ2UtMTUyMQ==","slug":"adding-bootstrap-iFg=","title":"Styling with Bootstrap"}},{"id":"T0E6OlBhZ2UtMTUyMQ==","title":"Styling with Bootstrap","slug":"adding-bootstrap-iFg=","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tNjIzNw==","title":"Styling with Bootstrap","htmlContent":"<p>Now that you have the user's experience mapped out and the functionality built, you can style your pages using Twitter's project <a href=\"http://getbootstrap.com/\" target=\"_blank\">Bootstrap</a>. Bootstrap is the web's most popular <strong>Design System</strong>.</p><p>The main elements we will be using are the...</p><ul>\n<li>Grid</li>\n<li>Navbar</li>\n<li>Forms</li>\n<li>Inputs</li>\n<li>Buttons</li>\n</ul><p>There is a lot more that you can explore and even extend and modify.</p>"},{"id":"T0E6OlNlY3Rpb24tNjIzOA==","title":"Adding Bootstrap with a Content Delivery Network (CDN)","htmlContent":"<p>It is easy to get started with bootstrap quickly by using the CDN links that bootstrap maintains.</p><p>We'll add the <code>&lt;link&gt;</code> to bootstrap's css in our <code>&lt;head&gt;</code> tag in the <code>views/layouts/main.handlebars</code> file. And although we aren't going to use any of bootstrap's JavaScript's components, for completeness's sake, we'll put the JavaScript <code>&lt;script&gt;</code> tag just before the closing <code>&lt;/body&gt;</code> tag.</p><div class=\"info\">\n<p></p>\n\n<p>You should always reference the <a href=\"https://www.bootstrapcdn.com/\" target=\"_blank\">latest Bootstrap CDN links</a> and use those to make sure everything is up to date.</p>\n</div><!-- --><div class=\"action\">\n<p>\nAdd the following <code>&lt;link&gt;</code> and <code>&lt;script&gt;</code> tags to <code>views/layouts/main.handlebars</code>:</p>\n<pre><span class=\"c\">&lt;!-- views/layouts/main.handlebars --&gt;</span>\n\n<span class=\"cp\">&lt;!doctype html&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">html</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">head</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">meta</span> <span class=\"na\">charset</span><span class=\"o\">=</span><span class=\"s\">\"utf-8\"</span><span class=\"p\">&gt;</span>\n  Make Parties\n  <span class=\"c\">&lt;!-- Latest compiled and minified CSS --&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">link</span> <span class=\"na\">rel</span><span class=\"o\">=</span><span class=\"s\">\"stylesheet\"</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css\"</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">head</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">body</span><span class=\"p\">&gt;</span>\n\n  {{{body}}}\n\n  <span class=\"c\">&lt;!-- Latest compiled and minified JavaScript --&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">script</span> <span class=\"na\">src</span><span class=\"o\">=</span><span class=\"s\">\"https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js\"</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">script</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">body</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">html</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>Just after doing that, refresh your page. The typography and layout should change just a tiny bit if it worked.</p>"},{"id":"T0E6OlNlY3Rpb24tNjIzOQ==","title":"Adding a Navbar","htmlContent":"<p>Add the most common navigational component - a top navbar. We'll have it contain a button to create a new event so that anywhere a user navigates to, they can always make a new event. If you shrink and grow the size of your browser window you'll notice that this is a <strong>responsive</strong> navbar, meaning it responds to the size of the screen.</p><p>To do this, we need to make a new <strong>partial</strong>. Partials are like html components that you can reuse in multiple views. They only contain enough html to render the component, hence why they're called a \"partial\".</p><div class=\"action\">\n<p>\nCreate a new folder <code>views/partials</code>, and then create a new file <code>navbar.handlebars</code> in that <code>views/partials</code> directory.</p>\n\n<p>Now add the following code to <code>views/partials/navbar.handlebars</code></p>\n<pre><span class=\"p\">&lt;</span><span class=\"nt\">nav</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"navbar navbar-expand-lg navbar-light bg-light\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"navbar-brand\"</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"#\"</span><span class=\"p\">&gt;</span>Make Parties<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n\n  <span class=\"p\">&lt;</span><span class=\"nt\">button</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"navbar-toggler\"</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"button\"</span> <span class=\"na\">data-toggle</span><span class=\"o\">=</span><span class=\"s\">\"collapse\"</span> <span class=\"na\">data-target</span><span class=\"o\">=</span><span class=\"s\">\"#navbarSupportedContent\"</span> <span class=\"na\">aria-controls</span><span class=\"o\">=</span><span class=\"s\">\"navbarSupportedContent\"</span> <span class=\"na\">aria-expanded</span><span class=\"o\">=</span><span class=\"s\">\"false\"</span> <span class=\"na\">aria-label</span><span class=\"o\">=</span><span class=\"s\">\"Toggle navigation\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">span</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"navbar-toggler-icon\"</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">span</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">button</span><span class=\"p\">&gt;</span>\n\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"collapse navbar-collapse\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">ul</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"navbar-nav mr-auto\"</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">li</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"nav-item active\"</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"nav-link\"</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/\"</span><span class=\"p\">&gt;</span>Home<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">nav</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>Great, now we need to add it to our <code>main</code> layout so that all pages will have it! We'll use Handlebar's <code>{{&gt; partial}}</code> syntax to inject the partial we just made into our main template.</p><div class=\"action\">\n<p></p>\n\n<p>Update <code>views/layouts/main.handlebars</code> to include the <code>navbar</code>:</p>\n<pre>...\n<span class=\"p\">&lt;</span><span class=\"nt\">body</span><span class=\"p\">&gt;</span>\n\n  {{&gt; navbar}}\n\n  {{{body}}}\n ...\n</pre>\n</div><p>If you refresh your browser, you should see the following:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P02-Adding-Bootstrap/assets/navbar.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P02-Adding-Bootstrap/assets/navbar.png\" alt=\"navbar\" title=\"\">\n        </a></p>"},{"id":"T0E6OlNlY3Rpb24tNjI0MA==","title":"Adding a Grid Container","htmlContent":"<p>People argue about the usefulness of some of the more complex parts of Bootstrap, but everyone agrees that to build websites you need a grid system.</p><p>Bootstrap ships with a 12-column grid. Meaning you can break up the whole page, or any element into 12 columns and construct an appealing layout.</p><div class=\"action\">\n<p></p>\n\n<p>Start by updating <code>views/layouts/main.handlebars</code> by wrapping the <code>{{{body}}}</code> with a <code>container</code> class.</p>\n</div>\n<pre><span class=\"c\">&lt;!-- views/layouts/main.handlebars --&gt;</span>\n...\n<span class=\"p\">&lt;</span><span class=\"nt\">body</span><span class=\"p\">&gt;</span>\n  ...\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"container\"</span><span class=\"p\">&gt;</span>\n    {{{body}}}\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n...\n</pre><p>Refresh and see that this gives us some satisfying gutters on the sides of the page. If we change the screen size by resizing the window, we'll see that these gutters vanish when our screen shrinks beyond a certain size. This is because Bootstrap's grid system is <strong>Responsive</strong>. This means that it <em>changes depending on the size of the screen that is being shown on.</em> Pretty neat!</p>"},{"id":"T0E6OlNlY3Rpb24tNjI0MQ==","title":"Adding a Responsive Grid with Cards","htmlContent":"<p>Let's add some bootstrap to make things look better. First we'll wrap things in a <code>row</code> (with a <code>margin-top</code> utility class) and some responsive columns so the events sit in the middle 6 columns of the page when the browser window is <code>lg</code> (large).</p><div class=\"action\">\n<p></p>\n\n<p>Update <code>views/events-index.handlebars</code> to the following:</p>\n<pre>  <span class=\"c\">&lt;!-- events-index --&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"row mt-4\"</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"col-lg-6 offset-lg-3\"</span><span class=\"p\">&gt;</span>\n          <span class=\"p\">&lt;</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>Events<span class=\"p\">&lt;/</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>\n          {{#each events}}\n              <span class=\"p\">&lt;</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>{{this.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>\n              <span class=\"p\">&lt;</span><span class=\"nt\">img</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"img-fluid\"</span> <span class=\"na\">src</span><span class=\"o\">=</span><span class=\"s\">\"{{this.imgUrl}}\"</span> <span class=\"na\">alt</span><span class=\"o\">=</span><span class=\"s\">\"Card image cap\"</span><span class=\"p\">&gt;</span>\n              <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>{{this.description}}<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n          {{/each}}\n      <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>Next we'll add some Bootstrap Card enhanced html inside of the <code>#each</code>:</p><div class=\"action\">\n<p></p>\n\n<p>Update the inside of the <code>#each</code> in <code>views/events-index.handlebars</code> to the following:</p>\n<pre>  {{#each events}}\n    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"card mt-3\"</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">img</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"card-img-top\"</span> <span class=\"na\">src</span><span class=\"o\">=</span><span class=\"s\">\"{{this.imgUrl}}\"</span> <span class=\"na\">alt</span><span class=\"o\">=</span><span class=\"s\">\"Card image cap\"</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"card-body\"</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">h5</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"card-title\"</span><span class=\"p\">&gt;</span>{{this.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">h5</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">p</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"card-text\"</span><span class=\"p\">&gt;</span>{{this.desc}}<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"text-right\"</span><span class=\"p\">&gt;</span>\n          <span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"#\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"btn btn-info\"</span><span class=\"p\">&gt;</span>Rsvp<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n          <span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"#\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"btn btn-primary\"</span><span class=\"p\">&gt;</span>View<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n  {{/each}}\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tNjI0Mg==","title":"Product So Far","htmlContent":"<p>Looks a lot nicer now, doesn't it?</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P02-Adding-Bootstrap/assets/bootstrap-added.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P02-Adding-Bootstrap/assets/bootstrap-added.png\" alt=\"bootstrap added\" title=\"\">\n        </a></p><p>Great work! Now let's actually build out those events!</p>"},{"id":"T0E6OlNlY3Rpb24tNjI0Mw==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Added vanilla bootstrap'</span>\n$ git push\n</pre>"}]},"next":{"id":"T0E6OlBhZ2UtMTUyMg==","slug":"creating-a-event","title":"New Event Form"},"previous":{"id":"T0E6OlBhZ2UtMTUyMg==","slug":"creating-a-event","title":"New Event Form"}},{"id":"T0E6OlBhZ2UtMTUyMg==","title":"New Event Form","slug":"creating-a-event","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tNjI0NA==","title":"New Event Form","htmlContent":"<p>Remember we are doing Resourceful and RESTful architecture to our MVC structured app. We've made some views in the <code>views</code> folder, instantiated a (fake) model, and put our controller logic (our routes) into the <code>app.js</code> file. As our model and controller logic grows, we can move them into other files. For this app it is so simple, that we'll just leave all that logic in the <code>app.js</code> file.</p><p>As for the <strong>Resourceful Routes</strong>, we've created just one: the index action for our <code>Event</code> resource.</p><p>Remember the previous table that showed a hypothetical set of routes for services like Instagram?</p><p>Here it is again for event:</p><table>\n<thead>\n<tr>\n<th>URL</th>\n<th>HTTP Verb</th>\n<th>Action</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>/events</td>\n<td>GET</td>\n<td>index</td>\n</tr>\n<tr>\n<td>/events/new</td>\n<td>GET</td>\n<td>new</td>\n</tr>\n<tr>\n<td>/events</td>\n<td>POST</td>\n<td>create</td>\n</tr>\n<tr>\n<td>/events/:id</td>\n<td>GET</td>\n<td>show</td>\n</tr>\n<tr>\n<td>/events/:id/edit</td>\n<td>GET</td>\n<td>edit</td>\n</tr>\n<tr>\n<td>/events/:id</td>\n<td>PATCH/PUT</td>\n<td>update</td>\n</tr>\n<tr>\n<td>/events/:id</td>\n<td>DELETE</td>\n<td>destroy</td>\n</tr>\n</tbody>\n</table><p>What do the routes look like for the app your are currently building?</p><table>\n<thead>\n<tr>\n<th>URL</th>\n<th>HTTP Verb</th>\n<th>Action</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>/</td>\n<td>GET</td>\n<td>index</td>\n</tr>\n</tbody>\n</table><p>Now we want to create two more for the <code>new</code> action, and the <code>create</code> action.</p><table>\n<thead>\n<tr>\n<th>URL</th>\n<th>HTTP Verb</th>\n<th>Action</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>/</td>\n<td>GET</td>\n<td>index</td>\n</tr>\n<tr>\n<td>/events/new</td>\n<td>GET</td>\n<td>new</td>\n</tr>\n<tr>\n<td>/events</td>\n<td>POST</td>\n<td>create</td>\n</tr>\n</tbody>\n</table>"},{"id":"T0E6OlNlY3Rpb24tNjI0NQ==","title":"Linking to New Event Route","htmlContent":"<p>First things first - what does the user see?</p><p>The user will have to click \"New Event\" to create a new event. So let's put a link into the <code>events-index</code> template.</p><div class=\"action\">\n<p></p>\n\n<p>Add the following <code>&lt;h1&gt;</code> and <code>&lt;a&gt;</code> into <code>views/events-index.handlebars</code>:</p>\n<pre><span class=\"c\">&lt;!-- views/events-index.handlebars --&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"row mt-4\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"col-lg-6 offset-lg-3\"</span><span class=\"p\">&gt;</span>\n        <span class=\"c\">&lt;!-- Add the following two lines --&gt;</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>Reviews<span class=\"p\">&lt;/</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/events/new\"</span><span class=\"p\">&gt;</span>New Event<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n\n        <span class=\"p\">&lt;</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>Events<span class=\"p\">&lt;/</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>\n        {{#each events}}\n        ...\n        {{/each}}\n    <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>When you click this link you should see a friendly error reminding you that we haven't made the route for <code>/events/new</code> yet.</p><p>Remember that errors are not bad. They are like sign posts that tell you what to do next. So let's add our route to this new path.</p>"},{"id":"T0E6OlNlY3Rpb24tNjI0Ng==","title":"New Event Form","htmlContent":"<p>Now we have to make a route to the <code>/events/new</code> path, and have it render a <code>events-new</code> template.</p><div class=\"action\">\n<p></p>\n\n<p>Add the following route to <code>app.js</code> to handle <code>/events/new</code>:</p>\n<pre><span class=\"c1\">// NEW</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/events/new'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'events-new'</span><span class=\"p\">,</span> <span class=\"p\">{});</span>\n<span class=\"p\">})</span>\n</pre>\n</div><p>If we navigate our browser to <code>/events/new</code> we'll get a friendly little error reminding us that we don't have a template called <code>events-new.handlebars</code> yet. So let's put that into our <code>views</code> folder.</p><div class=\"action\">\n<p></p>\n\n<p>Create the <code>views/events-new.handlebars</code> and add the following code to it:</p>\n<pre><span class=\"c\">&lt;!-- views/events-new.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">form</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">\"POST\"</span> <span class=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">\"/events\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">fieldset</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">legend</span><span class=\"p\">&gt;</span>New Event<span class=\"p\">&lt;/</span><span class=\"nt\">legend</span><span class=\"p\">&gt;</span>\n    <span class=\"c\">&lt;!-- TITLE --&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"title\"</span><span class=\"p\">&gt;</span>Title<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">br</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">input</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"text\"</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"title\"</span> <span class=\"p\">/&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"desc\"</span><span class=\"p\">&gt;</span>Movie Title<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">br</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">input</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"text\"</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"desc\"</span> <span class=\"p\">/&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">fieldset</span><span class=\"p\">&gt;</span>\n\n  <span class=\"c\">&lt;!-- BUTTON --&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">button</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"submit\"</span><span class=\"p\">&gt;</span>Save Event<span class=\"p\">&lt;/</span><span class=\"nt\">button</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n\n<span class=\"p\">&lt;/</span><span class=\"nt\">form</span><span class=\"p\">&gt;</span>\n</pre>\n</div><!-- --><div class=\"info\">\n<p>\nNotice a few things about our form. The form tag has an HTML attribute called <code>action</code> that has a value equal to the path we want our form to submit its data to. <code>/events</code> is the route to our create action that we will add to our server in the next step.</p>\n</div><p>Now if you navigate to <code>/events/new</code> you should see our new form looking great:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P03-A-New-Event-And-DB/assets/event-form.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P03-A-New-Event-And-DB/assets/event-form.png\" alt=\"event form\" title=\"\">\n        </a></p>"},{"id":"T0E6OlNlY3Rpb24tNjI0Nw==","title":"Event Create Action","htmlContent":"<p>If you try to submit our form now, we see the form sends a <strong>POST</strong> request to the url <code>/events</code>, but we have not made a route that detects post requests to that path. So we see our friendly error:</p><pre><span class=\"nx\">cannot</span> <span class=\"nx\">POST</span> <span class=\"nx\">to</span> <span class=\"o\">/</span><span class=\"nx\">events</span>\n</pre><p>Our server has no route called <code>/events</code> that accepts a POST HTTP method. So let's make one!</p><p>First, you need to get ready to accept form data using an npm module called <a href=\"https://expressjs.com/en/resources/middleware/body-parser.html\" target=\"_blank\">body-parser</a>.</p><div class=\"action\">\n<p></p>\n\n<p>Install <code>body-parser</code>:</p>\n<pre>$ npm install body-parser\n</pre>\n</div><p>Body Parser is a module that allows express to see form data that is coming in from a POST request. So we'll initialize the <code>body-parser</code> module in our <code>app.js</code> file.</p><div class=\"action\">\n<p></p>\n\n<p>Initialize the <code>body-parser</code> module in our <code>app.js</code> file:</p>\n<pre><span class=\"c1\">// app.js</span>\n<span class=\"p\">...</span>\n<span class=\"c1\">// INITIALIZE BODY-PARSER AND ADD IT TO APP</span>\n<span class=\"kr\">const</span> <span class=\"nx\">bodyParser</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'body-parser'</span><span class=\"p\">);</span>\n\n<span class=\"p\">...</span>\n<span class=\"c1\">// The following line must appear AFTER const app = express() and before your routes!</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">use</span><span class=\"p\">(</span><span class=\"nx\">bodyParser</span><span class=\"p\">.</span><span class=\"nx\">urlencoded</span><span class=\"p\">({</span> <span class=\"nx\">extended</span><span class=\"o\">:</span> <span class=\"kc\">true</span> <span class=\"p\">}));</span>\n\n<span class=\"p\">...</span>\n<span class=\"c1\">// CREATE</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">post</span><span class=\"p\">(</span><span class=\"s1\">'/events'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">body</span><span class=\"p\">);</span>\n<span class=\"p\">})</span>\n</pre>\n</div><p><code>body-parser</code> gives us a new attribute of the <code>req</code> object called <code>req.body</code> and this will contain the form data. So when you submit your form you should see it log in in your terminal like this:</p><pre><span class=\"p\">{</span> <span class=\"ss\">title</span><span class=\"p\">:</span> <span class=\"s1\">'Creating a Event'</span><span class=\"p\">,</span>\n  <span class=\"ss\">desc</span><span class=\"p\">:</span> <span class=\"s1\">'a sample event description'</span> <span class=\"p\">}</span>\n</pre><p>This is great, we're seeing the form data, but now we need to save this data to the database...</p>"},{"id":"T0E6OlNlY3Rpb24tNjI0OA==","title":"Setting up SQL","htmlContent":"<p>SQL&mdash;pronouced <em>ess-queue-el</em> or <em>see-quell</em>&mdash; is a kind of database and the name of the language used to query SQL databases.</p><p>For the purpose of this tutorial, we'll be using the <strong>PostgreSQL</strong> database&mdash;pronounced <em>post-gres-queue-el</em>.</p><p>We won't be writing an SQL queries though, because we are going to use an <strong>Object Relationship Mapper (ORM)</strong> to handle our queries for us. We will be using the most popular JavaScript SQL ORM called <strong>Sequelize.</strong></p><p>Since Sequelize's documentation is notoriously bad, refer to this alternative documentation we've written called <a href=\"https://ajbraus.github.io/sequelize-it\" target=\"_blank\">Sequelize-It</a>.</p><p>Our first step to setup a database is to add PostgreSQL to our environment.</p><h2>Cloud9</h2><p>If you have Cloud9 PostgreSQL is already installed and you can do the following to start your database.</p><div class=\"action\">\n<p></p>\n\n<p>Run the following command:</p>\n<pre>$ sudo service postgresql start\n</pre>\n</div><h2>Computer</h2><p>If you are running your development environment on your computer, you'll have to install Postgres.</p><div class=\"action\">\n<p></p>\n\n<ol>\n<li><p>Follow the steps outlined at <a href=\"https://postgresapp.com/\" target=\"_blank\">Postgres.app</a> to get everything set up.\n<strong>Note:</strong> Once you've installed, make sure to close/reopen your terminal for the changes to take effect.</p></li>\n<li><p>Now use <code>$ brew install postgresql</code> in your terminal to finish installing</p></li>\n</ol>\n</div>"},{"id":"T0E6OlNlY3Rpb24tNjI0OQ==","title":"Setting up Sequelize on your Project","htmlContent":"<p>Cool, Postgres installed, now we gotta work on Sequelize:</p><div class=\"action\">\n<p></p>\n\n<p>Follow the \"Quick Start: Getting Connected\" section in the <a href=\"https://ajbraus.github.io/sequelize-it/#/?id=quick-start-getting-connected\" target=\"_blank\">Sequelize-It</a> documentation.</p>\n\n<p><strong>IMPORTANT NOTE 1:</strong> It's very important to follow all 8 steps in the Quick Start, especially in terms of getting the <code>config.json</code> file set up correctly. If you run into <code>ECONNREFUSED</code> or <code>ETIMEDOUT</code> errors, go back to the guide and make sure you followed all 8 steps correctly.\n<strong>IMPORTANT NOTE 2:</strong> You must install all the sequalize libraries locally, not globally, otherwise they will not work in heroku.</p>\n\n<p>Local: \nExample: <code>npm install sequelize sequelize-cli pg pg-hstore</code></p>\n</div><p>You will need these packages to be available in both development and in production in heroku.</p>"},{"id":"T0E6OlNlY3Rpb24tNjI1MA==","title":"Creating your First Model & Migration","htmlContent":"<p>A <strong>Model</strong> is like a cookie cutter. You use it to define the attributes and behavior of a resource. Models are also used to interact with a database. We'll use our models every time we want to either save or read something from our database.</p><p>A <strong>Migration</strong> is some code we use to define the tables and columns of our SQL database. We always have to define the tables and columns before we try to read or write data to them.</p><p>These will make more sense once you start to use them, so hang tight.</p><p>Sequelize has a set of <strong>Generators</strong> for creating boilerplate code for models, seeders, and migrations. Let's use one of those generator commands to make our <code>Event</code> model and migration</p><div class=\"action\">\n<p></p>\n\n<p>Run the following command in your terminal to make the <code>Event</code> model and migration:</p>\n<pre>$ sequelize model:create --name Event --attributes title:string,desc:text\n</pre>\n</div><p>This command creates a model file, <code>db/models/event.js</code> (Notice it is singular), and a migration file <code>0984932849328-create-event.js</code>. That jumble of numbers is actually a date and time signature for the moment it was created. Every migration has one because migrations have to run in order, so they are run in the order of when they were created.</p><p>The important parts about are model are just the two attributes and their types: <code>title:STRING</code>, <code>desc:TEXT</code>. A <code>STRING</code> data type in SQL can have 255 bytes, and the <code>TEXT</code> data type can have unlimited text.</p><p>Later we'll use that <code>Event.associate</code> function to associate Rsvps with our event.</p><p>Our migration is a bit longer and adds a few other attributes to our Event:</p><ul>\n<li><code>id</code></li>\n<li><code>createdAt</code></li>\n<li><code>updatedAt</code></li>\n</ul><p>We'll use the <code>id</code> to fetch instances of events, and we'll use <code>createdAt</code> and <code>updatedAt</code> to order them.</p><div class=\"action\">\n<p>\n&lt;!-- &gt; First make sure your ports match what sequelize is expecting: port <strong>3306</strong>. Not doing this will throw an error when running the next command:</p>\n\n<p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P03-A-New-Event-And-DB/assets/port.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P03-A-New-Event-And-DB/assets/port.png\" alt=\"port\" title=\"\">\n        </a> --&gt;</p>\n\n<p>Start the server back up, and then run the migrations:</p>\n<pre>$ sequelize db:migrate\n</pre>\n</div><p>If you run into errors around <code>mysql</code> or <code>mysql2</code> not being installed, install them through npm (i.e. <code>npm install -g mysql2</code>) and then rerun the migration command.</p><p>Starting the migration adds the <code>Events</code> table to your database. Now we can save events to the database!</p><div class=\"info\">\n<p>\nIf you are on your own computer, you can download the program <a href=\"https://eggerapps.at/postico/\" target=\"_blank\">Postico</a> and you can examine and edit your database's contents and structure.</p>\n</div><p>One more step and we can commit our code...</p>"}]},"next":{"id":"T0E6OlBhZ2UtMTUyMw==","slug":"creating-a-event-Okk=","title":"Create Route: Saving a New Resource"},"previous":{"id":"T0E6OlBhZ2UtMTUyMw==","slug":"creating-a-event-Okk=","title":"Create Route: Saving a New Resource"}},{"id":"T0E6OlBhZ2UtMTUyMw==","title":"Create Route: Saving a New Resource","slug":"creating-a-event-Okk=","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tODI1Mg==","title":"Create Route: Saving a New Resource","htmlContent":"<p>So now we have</p><ol>\n<li>A new event form that is submitting data to our controller route</li>\n<li>An Event model</li>\n<li>And a database setup with an <code>Events</code> table.</li>\n</ol><p>So now we just need our <code>Event</code> model to save to our database.</p><ol>\n<li><del>Users can view all events (index)</del></li>\n<li><strong>Users can create a event (new/create)</strong></li>\n<li>Users can view one event (show)</li>\n<li>Users can edit a event (edit/update)</li>\n<li>Users can delete a event (destroy)</li>\n<li>Users can rsvp to events (/rsvps/create, /rsvps/new)</li>\n<li>Users can cancel their rsvp (/rsvps/destroy)</li>\n</ol>"},{"id":"T0E6OlNlY3Rpb24tODI1Mw==","title":"Using Form Data to Create a Event","htmlContent":"<p>So now let's use that form data to save a new event to our SQL database using our <code>Event</code> model. We'll use the method provided to us by Sequelize called <code>create()</code>. After we create the event, let's redirect to the root path to see our new event.</p><div class=\"action\">\n<p></p>\n\n<p>To access our models we have to require them into our <code>app.js</code>. Let's do that now near the top of <code>app.js</code>, underneath our <code>body-parser</code> code:</p>\n<pre><span class=\"kr\">const</span> <span class=\"nx\">models</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'./db/models'</span><span class=\"p\">);</span>\n</pre>\n</div><p>Now we can use this <code>models</code> variable to access our models in our routes:</p><div class=\"action\">\n<p></p>\n\n<p>Update the <code>/create</code> route in <code>app.js</code> to the following:</p>\n<pre><span class=\"c1\">// CREATE</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">post</span><span class=\"p\">(</span><span class=\"s1\">'/events'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">models</span><span class=\"p\">.</span><span class=\"nx\">Event</span><span class=\"p\">.</span><span class=\"nx\">create</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">body</span><span class=\"p\">).</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"nx\">event</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">redirect</span><span class=\"p\">(</span><span class=\"sb\">`/`</span><span class=\"p\">);</span>\n  <span class=\"p\">}).</span><span class=\"k\">catch</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">)</span>\n  <span class=\"p\">});</span>\n<span class=\"p\">})</span>\n</pre>\n</div><p>When you submit your form what do you see? Probably ... nothing yet! Because we aren't actually loading our events in <code>events-index</code> from our database. Let's add that using Sequelize's <code>findAll()</code> method:</p><div class=\"action\">\n<p></p>\n\n<p>Update the <code>/index</code> route in <code>app.js</code> to the following:</p>\n<pre><span class=\"c1\">// INDEX</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">models</span><span class=\"p\">.</span><span class=\"nx\">Event</span><span class=\"p\">.</span><span class=\"nx\">findAll</span><span class=\"p\">().</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"nx\">events</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'events-index'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">events</span><span class=\"o\">:</span> <span class=\"nx\">events</span> <span class=\"p\">});</span>\n  <span class=\"p\">})</span>\n<span class=\"p\">})</span>\n</pre>\n</div><p>Ok, now do you see your events? Can you add a few?</p><p>If you add a few, notice that new ones are going on the bottom, but that's not good, we want new events on the top. We can use the <code>order</code> option in the <code>findAll()</code> method. the <code>order</code> option takes an array of arrays that contain the attribute and either <code>ASCE</code> or <code>DESC</code> for ascending or descending order.</p><div class=\"action\">\n<p></p>\n\n<p>Update the <code>/index</code> route in <code>app.js</code> to the following:</p>\n<pre><span class=\"c1\">// Index</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">models</span><span class=\"p\">.</span><span class=\"nx\">Event</span><span class=\"p\">.</span><span class=\"nx\">findAll</span><span class=\"p\">({</span> <span class=\"nx\">order</span><span class=\"o\">:</span> <span class=\"p\">[[</span><span class=\"s1\">'createdAt'</span><span class=\"p\">,</span> <span class=\"s1\">'DESC'</span><span class=\"p\">]]</span> <span class=\"p\">}).</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"nx\">events</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'events-index'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">events</span><span class=\"o\">:</span> <span class=\"nx\">events</span> <span class=\"p\">});</span>\n  <span class=\"p\">})</span>\n<span class=\"p\">})</span>\n</pre>\n</div><p>Are you seeing your title and description text yet? Probably not because Handlebars went and added an extra layer to their library&mdash;ostensibly for security's sake&mdash;but for our purposes it just gets in the way. We're going to take this layer of security away to simplify building our project. </p><div class=\"action\">\n<p></p>\n\n<p>Follow the instructions posted on <a href=\"https://github.com/handlebars-lang/handlebars.js/issues/1648#issuecomment-582241258\" target=\"_blank\">this github issue</a>.\nIgnore changing your handlebars file extension to <code>.hbs</code>, just add the prototype access.</p>\n</div><p>Now the only problem is the images are not showing because we don't have an <code>imgUrl</code> attribute. Let's add that in the next step:</p>"},{"id":"T0E6OlNlY3Rpb24tODI1NA==","title":"Adding a New Attribute to our Model","htmlContent":"<p>The new action will be our form for making a new event. For now events just have one attribute <code>title</code>, but we can always add more. Let's add an attribute called <code>imgUrl</code> and another called <code>desc</code> so we can write some more details about the event we've done.</p><p>First let's add what the user sees - the <code>events-new.handlebars</code> form input field.</p><div class=\"action\">\n<p></p>\n\n<p>Update <code>views/events-new.handlebars</code> to include an input for <code>imgUrl</code> right below the movie title input:</p>\n<pre><span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"imgUrl\"</span><span class=\"p\">&gt;</span>Image Url<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">br</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">input</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"text\"</span> <span class=\"na\">placeholder</span><span class=\"o\">=</span><span class=\"s\">\"\"</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"imgUrl\"</span> <span class=\"p\">/&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>Next, let's create a migration:</p><div class=\"action\">\n<p></p>\n\n<p>Run the following in your terminal:\n<code>bash\n$ sequelize migration:create --name add-img-url-to-events\n</code></p>\n</div><p>Open the new migration that is created, and let's add the following <code>addColumn()</code> and <code>removeColumn()</code> methods into it:</p><div class=\"action\">\n<p></p>\n\n<p>Fill in the <code>up</code> and <code>down</code> methods with the following code in the <code>db/migrations/add-img-url-to-events.js</code> file:</p>\n<pre><span class=\"s1\">'use strict'</span><span class=\"p\">;</span>\n\n<span class=\"nx\">module</span><span class=\"p\">.</span><span class=\"nx\">exports</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n  <span class=\"nx\">up</span><span class=\"o\">:</span> <span class=\"p\">(</span><span class=\"nx\">queryInterface</span><span class=\"p\">,</span> <span class=\"nx\">Sequelize</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"k\">return</span> <span class=\"nx\">queryInterface</span><span class=\"p\">.</span><span class=\"nx\">addColumn</span><span class=\"p\">(</span><span class=\"s1\">'Events'</span><span class=\"p\">,</span> <span class=\"s1\">'imgUrl'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">type</span><span class=\"o\">:</span> <span class=\"nx\">Sequelize</span><span class=\"p\">.</span><span class=\"nx\">STRING</span> <span class=\"p\">});</span>\n  <span class=\"p\">},</span>\n\n  <span class=\"nx\">down</span><span class=\"o\">:</span> <span class=\"p\">(</span><span class=\"nx\">queryInterface</span><span class=\"p\">,</span> <span class=\"nx\">Sequelize</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"k\">return</span> <span class=\"nx\">queryInterface</span><span class=\"p\">.</span><span class=\"nx\">removeColumn</span><span class=\"p\">(</span><span class=\"s1\">'Events'</span><span class=\"p\">,</span> <span class=\"s1\">'imgUrl'</span><span class=\"p\">);</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">};</span>\n</pre>\n</div><!-- --><div class=\"info\">\n<p>\nMigrations should be <strong>reversible</strong> if possible. Meaning they can be run forwards to make a change, and run backwards to reverse that change. The <code>up</code> and <code>down</code> functions in a migration are made to run this way.</p>\n</div><p>Next, let's add the <code>imgUrl</code> attribute to the <code>Event</code> model.</p><div class=\"action\">\n<p></p>\n\n<p>Update the <code>Event</code> in <code>db/models/event.js</code> to include <code>imgUrl</code>:</p>\n<pre><span class=\"c1\">// db/models/event.js</span>\n<span class=\"p\">...</span>\n  <span class=\"kr\">const</span> <span class=\"nx\">Event</span> <span class=\"o\">=</span> <span class=\"nx\">sequelize</span><span class=\"p\">.</span><span class=\"nx\">define</span><span class=\"p\">(</span><span class=\"s1\">'Event'</span><span class=\"p\">,</span> <span class=\"p\">{</span>\n    <span class=\"nx\">title</span><span class=\"o\">:</span> <span class=\"nx\">DataTypes</span><span class=\"p\">.</span><span class=\"nx\">STRING</span><span class=\"p\">,</span>\n    <span class=\"nx\">desc</span><span class=\"o\">:</span> <span class=\"nx\">DataTypes</span><span class=\"p\">.</span><span class=\"nx\">TEXT</span><span class=\"p\">,</span>\n    <span class=\"nx\">imgUrl</span><span class=\"o\">:</span> <span class=\"nx\">DataTypes</span><span class=\"p\">.</span><span class=\"nx\">STRING</span> <span class=\"c1\">//add this line (don't forget the comma above!)</span>\n  <span class=\"p\">},</span> <span class=\"p\">{});</span>\n<span class=\"p\">...</span>\n</pre>\n</div><p>Can you resubmit the form? What happens now? Is it hanging? Did you get an error? That's because we forgot to run the migration and actually update our database <code>Events</code> table:</p><div class=\"action\">\n<p></p>\n\n<p>Run the migration!</p>\n<pre>$ sequelize db:migrate\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODI1NQ==","title":"Product So Far","htmlContent":"<p>Ok now resubmit the form... can you see your image on your newest event with an image?</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P04-Creating-An-Event/assets/dog-icon.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P04-Creating-An-Event/assets/dog-icon.png\" alt=\"dogicon\" title=\"\">\n        </a></p>"},{"id":"T0E6OlNlY3Rpb24tODI1Ng==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can create events'</span>\n$ git push\n</pre>"},{"id":"T0E6OlNlY3Rpb24tODI1Nw==","title":"Stretch Challenge: Adding a TakesPlaceOn Attribute","htmlContent":"<div class=\"challenge\">\n<p></p>\n\n<p>Events have to take place on a certain day. Can you add a <code>takesPlaceOn</code> attribute that is a <code>Date</code>, and then use <code>&lt;input type=\"date\"&gt;</code> elements? You might have to google for an example to see how this works.</p>\n</div>"}]},"next":{"id":"T0E6OlBhZ2UtMTUyNA==","slug":"showing-one-event","title":"Show Route: See One Resource"},"previous":{"id":"T0E6OlBhZ2UtMTUyNA==","slug":"showing-one-event","title":"Show Route: See One Resource"}},{"id":"T0E6OlBhZ2UtMTUyNA==","title":"Show Route: See One Resource","slug":"showing-one-event","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tMTA2MDU=","title":"Show Route: See One Resource","htmlContent":"<ol>\n<li><del>Users can view all events (index)</del></li>\n<li><del>Users can create a event (new/create)</del></li>\n<li><strong>Users can view one event (show)</strong></li>\n<li>Users can edit a event (edit/update)</li>\n<li>Users can delete a event (destroy)</li>\n<li>Users can rsvp to events (/rsvps/create, /rsvps/new)</li>\n<li>Users can cancel their rsvp (/rsvps/destroy)</li>\n</ol><p>We are building out all the <strong>Resourceful Routes</strong> for our <code>Event</code> resource.</p><table>\n<thead>\n<tr>\n<th>URL</th>\n<th>HTTP Verb</th>\n<th>Action</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>/</td>\n<td>GET</td>\n<td>index</td>\n</tr>\n<tr>\n<td>/events/new</td>\n<td>GET</td>\n<td>new</td>\n</tr>\n<tr>\n<td>/events</td>\n<td>POST</td>\n<td>create</td>\n</tr>\n<tr>\n<td>/events/:id</td>\n<td>GET</td>\n<td>show</td>\n</tr>\n</tbody>\n</table><p>We've already completed the index, new, and create actions. Now you will add a show action that will display a single resource via it's <code>id</code>.</p><p>Now let's setup the <strong>show</strong> action so we give each single event its own page and unique url path.</p>"},{"id":"T0E6OlNlY3Rpb24tMTA2MDY=","title":"Show One Event","htmlContent":"<p>Remember, always start by building what the user will see and do. To create the show action, you will want to start by making a link to the event from our index action template. Your route has to follow the <code>/events/:id</code> structure.</p><p>SQL automatically creates an <code>id</code> attribute on anything you save. So we can use that <code>id</code> attribute for our <code>:id</code> in the route. This is called the <strong>Url or Request Parameter</strong> and we access it in Express using the <code>req.params</code> parameter inside a controller route.</p><div class=\"action\">\n<p></p>\n\n<p>Add the <code>View</code> link in <code>views/events-index.handlebars</code> to the following:</p>\n<pre><span class=\"c\">&lt;!-- views/events-index.handlebars --&gt;</span>\n\n...\n<span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/events/{{this.id}}\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"btn btn-primary\"</span><span class=\"p\">&gt;</span>View<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n...\n</pre>\n</div><p>What happens if you click on that link? A friendly error! Let's do what it says and make the route.</p><div class=\"action\">\n<p></p>\n\n<p>Build the <code>/show</code> route in <code>app.js</code>:</p>\n<pre><span class=\"c1\">// app.js</span>\n\n<span class=\"p\">...</span>\n\n<span class=\"c1\">// SHOW</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/events/:id'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">send</span><span class=\"p\">(</span><span class=\"s1\">'I\\'m an event'</span><span class=\"p\">)</span>\n<span class=\"p\">});</span>\n</pre>\n</div><p>Now what happens if you go to that route? It should say the text we are sending back. That's good! That means the route is working. Now let's take the next step.</p><p><em>Taking baby steps like this is a GREAT habit as a software engineer. Aim to take many small steps at a good pace.</em></p>"},{"id":"T0E6OlNlY3Rpb24tMTA2MDc=","title":"req.params & Event.findByPk()","htmlContent":"<p>Ok time to add a template with an actual <code>event</code> object! We'll update our <code>/show</code> route to find the event we're looking for by its <code>id</code> using sequelize's <a href=\"http://docs.sequelizejs.com/class/lib/model.js%7EModel.html#static-method-findByPk\" target=\"_blank\">findByPk</a> method, which searches for a single instance by its primary key (which is the event <code>id</code>, in this case).</p><div class=\"action\">\n<p></p>\n\n<p>Replace your stub <code>/show</code> route in <code>app.js</code> with the following:</p>\n<pre><span class=\"c1\">// app.js</span>\n\n<span class=\"p\">...</span>\n\n<span class=\"c1\">// SHOW</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/events/:id'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// Search for the event by its id that was passed in via req.params</span>\n  <span class=\"nx\">models</span><span class=\"p\">.</span><span class=\"nx\">Event</span><span class=\"p\">.</span><span class=\"nx\">findByPk</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">id</span><span class=\"p\">).</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">event</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"c1\">// If the id is for a valid event, show it</span>\n    <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'events-show'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">event</span><span class=\"o\">:</span> <span class=\"nx\">event</span> <span class=\"p\">})</span>\n  <span class=\"p\">}).</span><span class=\"k\">catch</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"c1\">// if they id was for an event not in our db, log an error</span>\n    <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">.</span><span class=\"nx\">message</span><span class=\"p\">);</span>\n  <span class=\"p\">})</span>\n<span class=\"p\">})</span>\n</pre>\n</div><p>Now if we go to the route, we'll see the error that no template <code>events-show</code> is found. That's great! We knew that didn't exist, so we were expecting this error. The program is working! Let's make the template now.</p><div class=\"action\">\n<p></p>\n\n<p>Create a new file <code>views/events-show.handlebars</code>, and put the following code in it:</p>\n<pre><span class=\"c\">&lt;!-- views/events-show.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">img</span> <span class=\"na\">src</span><span class=\"o\">=</span><span class=\"s\">{{event.imgUrl}}</span> <span class=\"p\">/&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>{{event.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>{{event.desc}}<span class=\"p\">&lt;/</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>\n</pre>\n</div><!-- --><div class=\"info\">\n<p>\nYou might need to add <code>dataValues</code>, (e.g. <code>event.dataValues.imgUrl</code>, <code>event.dataValues.title</code>, <code>event.dataValues.desc</code>) to make attributes render depending on your OS, and handlebars.</p>\n</div><p>Now what do you see? All the <code>View</code> links to events should work now!</p>"},{"id":"T0E6OlNlY3Rpb24tMTA2MDg=","title":"Update the Create Action's Redirect","htmlContent":"<p>It makes sense from the user's perspective that after we create a new event, we should be automatically redirected to it, no? Let's change our create route to redirect to the show path.</p><div class=\"action\">\n<p></p>\n\n<p>Update the <code>redirect</code> line in your <code>/create</code> route in <code>app.js</code> to the following:</p>\n<pre><span class=\"c1\">// CREATE</span>\n<span class=\"p\">...</span>\n<span class=\"c1\">// CREATE</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">post</span><span class=\"p\">(</span><span class=\"s1\">'/events'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">models</span><span class=\"p\">.</span><span class=\"nx\">Event</span><span class=\"p\">.</span><span class=\"nx\">create</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">body</span><span class=\"p\">).</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"nx\">event</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"c1\">// Redirect to events/:id</span>\n<strong>    <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">redirect</span><span class=\"p\">(</span><span class=\"sb\">`/events/</span><span class=\"si\">${</span><span class=\"nx\">event</span><span class=\"p\">.</span><span class=\"nx\">id</span><span class=\"si\">}</span><span class=\"sb\">`</span><span class=\"p\">)</span>\n</strong>\n  <span class=\"p\">}).</span><span class=\"k\">catch</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">)</span>\n  <span class=\"p\">});</span>\n<span class=\"p\">})</span>\n<span class=\"p\">...</span>\n<span class=\"p\">})</span></pre>\n</div><p>Try adding a new event now, and make sure it takes you to the <code>events-show</code> page after you create it.</p>"},{"id":"T0E6OlNlY3Rpb24tMTA2MDk=","title":"Adding some Bootstrap","htmlContent":"<p>Let's make that show template a little prettier with some bootstrap.</p><p>We'll wrap it in a responsive row and columns with an offset so its in the middle 6 columns of our container. We'll also add some classes that make the image responsively the full width (<code>w-100</code> = width 100%), rounded corners, and a margin bottom level 3. And we'll use the <code>.lead</code> class to fancy-up the description text.</p><div class=\"action\">\n<p></p>\n\n<p>Update <code>views/events-show.handlebars</code> to the following:</p>\n<pre><span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"row mt-4\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"col-lg-6 offset-lg-3\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">img</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"img-fluid w-100 rounded mb-3\"</span> <span class=\"na\">src</span><span class=\"o\">=</span><span class=\"s\">\"{{event.imgUrl}}\"</span> <span class=\"na\">alt</span><span class=\"o\">=</span><span class=\"s\">\"Card image cap\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">h3</span><span class=\"p\">&gt;</span>{{event.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">h3</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"lead\"</span><span class=\"p\">&gt;</span>{{event.desc}}<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tMTA2MTA=","title":"Product so Far","htmlContent":"<p>Check out your new event page!</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P05-Showing-One-Event/assets/event-show.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P05-Showing-One-Event/assets/event-show.png\" alt=\"event-show\" title=\"\">\n        </a></p><p>Now let's commit!</p>"},{"id":"T0E6OlNlY3Rpb24tMTA2MTE=","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can see single events'</span>\n$ git push\n</pre><p>Now our user experience is getting very smooth, and our code is getting more and more complete. Onward!</p>"}]},"next":{"id":"T0E6OlBhZ2UtMTUyNQ==","slug":"editing-a-event","title":"Edit Route: Editing and Updating a Resource"},"previous":{"id":"T0E6OlBhZ2UtMTUyNQ==","slug":"editing-a-event","title":"Edit Route: Editing and Updating a Resource"}},{"id":"T0E6OlBhZ2UtMTUyNQ==","title":"Edit Route: Editing and Updating a Resource","slug":"editing-a-event","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tODI2NA==","title":"Edit Route: Editing and Updating a Resource","htmlContent":"<ol>\n<li><del>Users can view all events (index)</del></li>\n<li><del>Users can create a event (new/create)</del></li>\n<li><del>Users can view one event (show)</del></li>\n<li><strong>Users can edit a event (edit/update)</strong></li>\n<li>Users can delete a event (destroy)</li>\n<li>Users can rsvp to events (/rsvps/create, /rsvps/new)</li>\n<li>Users can cancel their rsvp (/rsvps/destroy)</li>\n</ol><p>Now we're checking off the seven <strong>Resourceful Routes</strong>. But we're not done until all of them are complete.</p><table>\n<thead>\n<tr>\n<th>URL</th>\n<th>HTTP Verb</th>\n<th>Action</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>/</td>\n<td>GET</td>\n<td>index</td>\n</tr>\n<tr>\n<td>/events/new</td>\n<td>GET</td>\n<td>new</td>\n</tr>\n<tr>\n<td>/events</td>\n<td>POST</td>\n<td>create</td>\n</tr>\n<tr>\n<td>/events/:id</td>\n<td>GET</td>\n<td>show</td>\n</tr>\n<tr>\n<td>/events/:id/edit</td>\n<td>GET</td>\n<td>edit</td>\n</tr>\n<tr>\n<td>/events/:id</td>\n<td>PUT/PATCH</td>\n<td>update</td>\n</tr>\n</tbody>\n</table><p>Normally in a site like Eventbrite, we would only want authors of events to have the permission to edit or delete a event. However, because we do not have authentication yet, we're just going to let anyone edit and delete events.</p>"},{"id":"T0E6OlNlY3Rpb24tODI2NQ==","title":"Edit Link","htmlContent":"<p>We want people to be able to edit and update events, let's again start from the user's perspective. Edit and Update are similar to New and Create:</p><ul>\n<li>First we need a link to the edit route that renders a form template called <code>events-edit</code>\n</li>\n<li>Then we submit that edit form to the update route which will redirect to the show action.</li>\n</ul><p>So let's make the edit link inside our responsive row and middle 6 columns:</p><div class=\"action\">\n<p></p>\n\n<p>Place the edit link directly underneath the <code>div</code> for <code>desc</code> in <code>views/events-show.handlebars</code>:</p>\n<pre><span class=\"c\">&lt;!-- views/events-show.handlebars --&gt;</span>\n\n...\n\n    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"text-right\"</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/events/{{event.id}}/edit\"</span><span class=\"p\">&gt;</span>Edit<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n...\n</pre>\n</div><p>Ok now if we click that edit link, we'll see correctly that the route is not found. So let's make our edit action.</p><p>The edit action is like the show action because we look up the <code>event</code> by its <code>id</code> in the url parameter, but then we render the information in a template as editable form elements.</p><div class=\"action\">\n<p></p>\n\n<p>Add the <code>/edit</code> route in <code>app.js</code>:</p>\n<pre><span class=\"c1\">// app.js</span>\n\n<span class=\"p\">...</span>\n\n<span class=\"c1\">// EDIT</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/events/:id/edit'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">models</span><span class=\"p\">.</span><span class=\"nx\">Event</span><span class=\"p\">.</span><span class=\"nx\">findByPk</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">id</span><span class=\"p\">).</span><span class=\"nx\">then</span><span class=\"p\">((</span><span class=\"nx\">event</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'events-edit'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">event</span><span class=\"o\">:</span> <span class=\"nx\">event</span> <span class=\"p\">});</span>\n  <span class=\"p\">}).</span><span class=\"k\">catch</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">.</span><span class=\"nx\">message</span><span class=\"p\">);</span>\n  <span class=\"p\">})</span>\n<span class=\"p\">});</span>\n</pre>\n</div><p>And of course we'll need that <code>events-edit</code> template. This template is a bit weird for three reasons:</p><ol>\n<li>\n<strong><code>value=\"\"</code></strong> - The form needs to display the current values of the event's attributes. We are using the <code>value</code> html attribute to pass in the values of the event we are trying to edit.</li>\n<li>\n<strong><code>&lt;textarea&gt;{{}}&lt;/textarea&gt;</code></strong> - the <code>&lt;textarea&gt;</code> HTML tag does not have a <code>value</code> attribute, so its contents must go between its open and close tags.</li>\n<li>\n<strong>PUT vs. POST</strong> - Our update action will be expecting a <code>PUT</code> HTTP action; however, HTML forms cannot take an action attribute of <code>PUT</code> only <code>POST</code>. We must find a sensible work around to HTML's shortcomings. We'll use a piece of middleware called <code>methodOverride</code> to get the right method. What we'll do is add this middleware and then add <code>?_method=PUT</code> onto the end of the action. This way the server will be able to intercept the POST request and set it to PUT and then direct it towards our update action that takes a PUT HTTP request.</li>\n</ol><p>Let's start by building out the responsive row and columns</p><div class=\"action\">\n<p></p>\n\n<p>Create the <code>views/events-edit.handlebars</code> file and add the following code to it:</p>\n<pre><span class=\"c\">&lt;!-- views/events-edit.handlebars --&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"row mt-4\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"col-lg-6 offset-lg-3\"</span><span class=\"p\">&gt;</span>\n\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n</pre>\n<p>Now add the Card boilerplate inside <code>&lt;div class=\"col-lg-6 offset-lg-3\"&gt;</code> from above:</p>\n<pre><span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"card\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"card-body\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"card-title\"</span><span class=\"p\">&gt;</span>\n      <span class=\"p\">&lt;</span><span class=\"nt\">h3</span><span class=\"p\">&gt;</span>Update Event<span class=\"p\">&lt;/</span><span class=\"nt\">h3</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"card-text\"</span><span class=\"p\">&gt;</span>\n\n    <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n</pre>\n<p>Finally, add the form into the <code>.card-text</code> block from above:</p>\n<pre><span class=\"p\">&lt;</span><span class=\"nt\">form</span> <span class=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">\"/events/{{event.id}}?_method=PUT\"</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">\"post\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-group\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"title\"</span><span class=\"p\">&gt;</span>Title<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">input</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"title\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-control\"</span> <span class=\"na\">placeholder</span><span class=\"o\">=</span><span class=\"s\">\"Pickup Basketball\"</span> <span class=\"na\">value</span><span class=\"o\">=</span><span class=\"s\">\"{{event.title}}\"</span> <span class=\"p\">/&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-group\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"imgUrl\"</span><span class=\"p\">&gt;</span>Image Url<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">input</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"imgUrl\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-control\"</span> <span class=\"na\">placeholder</span><span class=\"o\">=</span><span class=\"s\">\"\"</span> <span class=\"na\">value</span><span class=\"o\">=</span><span class=\"s\">\"{{event.imgUrl}}\"</span><span class=\"p\">/&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-group\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"desc\"</span><span class=\"p\">&gt;</span>Description<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">textarea</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"desc\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-control\"</span> <span class=\"na\">placeholder</span><span class=\"o\">=</span><span class=\"s\">\"A description of your event.\"</span><span class=\"p\">&gt;</span>{{event.desc}}<span class=\"p\">&lt;/</span><span class=\"nt\">textarea</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"text-right\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/events/{{event.id}}\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">'text-muted mr-2'</span><span class=\"p\">&gt;</span>Cancel<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">button</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"submit\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"btn btn-primary\"</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"button\"</span><span class=\"p\">&gt;</span>Update<span class=\"p\">&lt;/</span><span class=\"nt\">button</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">form</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>Here's an example of what the form should look like at this point:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P06-Editing-An-Event/assets/edit-form.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P06-Editing-An-Event/assets/edit-form.png\" alt=\"edit-form\" title=\"\">\n        </a></p><p>If you submit this form now, it will say there is no POST route to this path. We have to initialize the <code>methodOverride</code> middleware to direct this route to the PUT update action.</p>"},{"id":"T0E6OlNlY3Rpb24tODI2Ng==","title":"Update Route","htmlContent":"<p>Remember that you needed to intercept this POST request and make sure its processed as a PUT request so it goes to our update action. (this will work for our delete action later too!). We'll use the <a href=\"https://github.com/expressjs/method-override\" target=\"_blank\">method-override</a> middleware.</p><div class=\"action\">\n<p></p>\n\n<p>install method-override:</p>\n<pre>$ npm install method-override --save\n</pre>\n</div><p>After importing the new package use <code>require('method-override')</code> to import it into your project.</p><div class=\"action\">\n<p></p>\n\n<p>Now add <code>methodOverride</code> as middleware after <code>const express = require('express')</code> but before your routes.</p>\n<pre><span class=\"kr\">const</span> <span class=\"nx\">express</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'express'</span><span class=\"p\">)</span>\n<span class=\"kr\">const</span> <span class=\"nx\">methodOverride</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'method-override'</span><span class=\"p\">)</span>\n\n<span class=\"p\">...</span>\n\n<span class=\"kr\">const</span> <span class=\"nx\">app</span> <span class=\"o\">=</span> <span class=\"nx\">express</span><span class=\"p\">()</span>\n\n<span class=\"p\">...</span>\n\n<span class=\"c1\">// override with POST having ?_method=DELETE or ?_method=PUT</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">use</span><span class=\"p\">(</span><span class=\"nx\">methodOverride</span><span class=\"p\">(</span><span class=\"s1\">'_method'</span><span class=\"p\">))</span>\n</pre>\n</div><p>Now you can create your update action and it will receive requests with a PUT method.</p><div class=\"action\">\n<p></p>\n\n<p>Add the <code>/update</code> route to <code>app.js</code>:</p>\n<pre><span class=\"c1\">// app.js</span>\n<span class=\"p\">...</span>\n\n<span class=\"c1\">// UPDATE</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">put</span><span class=\"p\">(</span><span class=\"s1\">'/events/:id'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">models</span><span class=\"p\">.</span><span class=\"nx\">Event</span><span class=\"p\">.</span><span class=\"nx\">findByPk</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">id</span><span class=\"p\">).</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"nx\">event</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">event</span><span class=\"p\">.</span><span class=\"nx\">update</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">body</span><span class=\"p\">).</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"nx\">event</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">redirect</span><span class=\"p\">(</span><span class=\"sb\">`/events/</span><span class=\"si\">${</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">id</span><span class=\"si\">}</span><span class=\"sb\">`</span><span class=\"p\">);</span>\n    <span class=\"p\">}).</span><span class=\"k\">catch</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">);</span>\n    <span class=\"p\">});</span>\n  <span class=\"p\">}).</span><span class=\"k\">catch</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">);</span>\n  <span class=\"p\">});</span>\n<span class=\"p\">});</span>\n</pre>\n</div><p>Make sure you're able to edit an event!</p>"},{"id":"T0E6OlNlY3Rpb24tODI2Nw==","title":"DRY Code & Sub Templates","htmlContent":"<p>Did you notice that the code of our <code>events-new</code> and <code>events-edit</code> have a lot of similarities? Pretty much everything inside the <code>form</code> tag is the same. Let's use a <strong>Partial Template</strong> to pull that code out into its own template.</p><div class=\"action\">\n<p></p>\n\n<p>Create <code>views/partials/events-form.handlebars</code> with the following code:</p>\n<pre><span class=\"c\">&lt;!-- views/partials/events-form.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-group\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"title\"</span><span class=\"p\">&gt;</span>Title<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">input</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"title\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-control\"</span> <span class=\"na\">placeholder</span><span class=\"o\">=</span><span class=\"s\">\"Pickup Basketball\"</span> <span class=\"na\">value</span><span class=\"o\">=</span><span class=\"s\">\"{{event.title}}\"</span> <span class=\"p\">/&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-group\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"desc\"</span><span class=\"p\">&gt;</span>Description<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">textarea</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"desc\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-control\"</span> <span class=\"na\">placeholder</span><span class=\"o\">=</span><span class=\"s\">\"A description of your event.\"</span><span class=\"p\">&gt;</span>{{event.desc}}<span class=\"p\">&lt;/</span><span class=\"nt\">textarea</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-group\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"imgUrl\"</span><span class=\"p\">&gt;</span>Image Url<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">input</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"imgUrl\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-control\"</span> <span class=\"na\">placeholder</span><span class=\"o\">=</span><span class=\"s\">\"\"</span> <span class=\"na\">value</span><span class=\"o\">=</span><span class=\"s\">\"{{event.imgUrl}}\"</span><span class=\"p\">/&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>And now we can use this partial to replace that information in both our new and edit templates.</p><div class=\"action\">\n<p></p>\n\n<p>Update both <code>views/events-new.handlebars</code> and <code>views/events-edit.handlebars</code> to the following:</p>\n\n<p><strong>events-new</strong></p>\n<pre><span class=\"c\">&lt;!-- views/events-new.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">form</span> <span class=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">\"/events\"</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">\"post\"</span><span class=\"p\">&gt;</span>\n  {{&gt; events-form }}\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"text-right\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">button</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"submit\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"btn btn-primary\"</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"button\"</span><span class=\"p\">&gt;</span>Save<span class=\"p\">&lt;/</span><span class=\"nt\">button</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">form</span><span class=\"p\">&gt;</span>\n...\n</pre>\n<p><strong>events-edit</strong></p>\n<pre><span class=\"c\">&lt;!-- views/events-edit.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"row mt-4\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"col-lg-6 offset-lg-3\"</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"card\"</span><span class=\"p\">&gt;</span>\n            <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"card-body\"</span><span class=\"p\">&gt;</span>\n                <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"card-title\"</span><span class=\"p\">&gt;</span>\n                    <span class=\"p\">&lt;</span><span class=\"nt\">h3</span><span class=\"p\">&gt;</span>Update Event<span class=\"p\">&lt;/</span><span class=\"nt\">h3</span><span class=\"p\">&gt;</span>\n                <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n                <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"card-text\"</span><span class=\"p\">&gt;</span>\n                    <span class=\"p\">&lt;</span><span class=\"nt\">form</span> <span class=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">\"/events/{{event.id}}?_method=PUT\"</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">\"post\"</span><span class=\"p\">&gt;</span>\n                        {{&gt; events-form }}\n                        <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"text-right\"</span><span class=\"p\">&gt;</span>\n                            <span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/events/{{event.id}}\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">'text-muted mr-2'</span><span class=\"p\">&gt;</span>Cancel<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n                            <span class=\"p\">&lt;</span><span class=\"nt\">button</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"submit\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"btn btn-primary\"</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"button\"</span><span class=\"p\">&gt;</span>Update<span class=\"p\">&lt;/</span><span class=\"nt\">button</span><span class=\"p\">&gt;</span>\n                        <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n                    <span class=\"p\">&lt;/</span><span class=\"nt\">form</span><span class=\"p\">&gt;</span>\n                <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n            <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>Triumph! DRY code. (Don't Repeat Yourself). Be sure to test your code though by creating a new event and editing an event to make sure everything still works properly.</p><p><strong>Reminder</strong> - Do not make partials unless the code is very long or repeated. Otherwise you are running the risk of \"overengineering\" your code.</p>"},{"id":"T0E6OlNlY3Rpb24tODI2OA==","title":"Product So Far","htmlContent":"<p>Things are really starting to come together! Check out how nice our new event page looks now that we're using our styled partial for the form:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P06-Editing-An-Event/assets/styled-new.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P06-Editing-An-Event/assets/styled-new.png\" alt=\"styled-new\" title=\"\">\n        </a></p>"},{"id":"T0E6OlNlY3Rpb24tODI2OQ==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can edit and update events'</span>\n$ git push\n</pre>"},{"id":"T0E6OlNlY3Rpb24tODI3MA==","title":"Stretch Challenge: \"Cancel\" buttons","htmlContent":"<div class=\"challenge\">\n<p></p>\n\n<p>Sometimes people might start making a resource and then want to cancel. Can you add a \"Cancel\" button next to the \"Save Event\" button? What will it do? Where will it link to?</p>\n</div>"}]},"next":{"id":"T0E6OlBhZ2UtMTUyNg==","slug":"deleting-a-event","title":"Delete Route: Destroying a Resource"},"previous":{"id":"T0E6OlBhZ2UtMTUyNg==","slug":"deleting-a-event","title":"Delete Route: Destroying a Resource"}},{"id":"T0E6OlBhZ2UtMTUyNg==","title":"Delete Route: Destroying a Resource","slug":"deleting-a-event","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tODM4MQ==","title":"Delete Route: Destroying a Resource","htmlContent":"<ol>\n<li><del>Users can view all events (index)</del></li>\n<li><del>Users can create a event (new/create)</del></li>\n<li><del>Users can view one event (show)</del></li>\n<li><del>Users can edit a event (edit/update)</del></li>\n<li><strong>Users can delete a event (destroy)</strong></li>\n<li>Users can rsvp to events (/rsvps/create, /rsvps/new)</li>\n<li>Users can cancel their rsvp (/rsvps/destroy)</li>\n</ol><p>So we've come to the end of our RESTful and Resourceful routes. Only one to go: Destroy!</p><table>\n<thead>\n<tr>\n<th>URL</th>\n<th>HTTP Verb</th>\n<th>Action</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>/</td>\n<td>GET</td>\n<td>index</td>\n</tr>\n<tr>\n<td>/events/new</td>\n<td>GET</td>\n<td>new</td>\n</tr>\n<tr>\n<td>/events</td>\n<td>POST</td>\n<td>create</td>\n</tr>\n<tr>\n<td>/events/:id</td>\n<td>GET</td>\n<td>show</td>\n</tr>\n<tr>\n<td>/events/:id/edit</td>\n<td>GET</td>\n<td>edit</td>\n</tr>\n<tr>\n<td>/events/:id</td>\n<td>PUT/PATCH</td>\n<td>update</td>\n</tr>\n<tr>\n<td>/events/:id</td>\n<td>DELETE</td>\n<td>Destroy</td>\n</tr>\n</tbody>\n</table>"},{"id":"T0E6OlNlY3Rpb24tODM4Mg==","title":"What the User Sees","htmlContent":"<p>As always, we start with what the users sees and does. So let's make a link to delete an event. We'll put it in the edit form so people don't click it accidentally.</p><p>We can't set an <code>&lt;a&gt;</code> tag's method (it is always GET) so we are going to use a form to submit a DELETE request to our delete action path.</p><div class=\"action\">\n<p></p>\n\n<p>Add the following delete form to <code>views/events-edit.handlebars</code> following the pre-existing edit form block:</p>\n<pre><span class=\"c\">&lt;!-- views/events-edit.handlebars --&gt;</span>\n...\n<span class=\"p\">&lt;</span><span class=\"nt\">form</span> <span class=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">\"/events/{{event.id}}?_method=PUT\"</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">\"post\"</span><span class=\"p\">&gt;</span>\n    ...\n<span class=\"p\">&lt;/</span><span class=\"nt\">form</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">form</span> <span class=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">\"/events/{{event.id}}?_method=DELETE\"</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">\"POST\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">button</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"submit\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">'btn btn-danger'</span><span class=\"p\">&gt;</span>Delete<span class=\"p\">&lt;/</span><span class=\"nt\">button</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">form</span><span class=\"p\">&gt;</span>\n...\n</pre>\n</div><p><strong>Careful not to put a form inside another form. Neither will work.</strong></p><p>Your events-edit template should look like this:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P07-Deleting-A-Event/assets/edit-page.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P07-Deleting-A-Event/assets/edit-page.png\" alt=\"events-edit\" title=\"\">\n        </a></p><p>But there is no DELETE route, so if you submit this you'll get a helpful error telling you that. So we need a delete action route. After deleting the event, it should redirect to the home page (<code>events-index</code>) because the event will be gone.</p><div class=\"action\">\n<p></p>\n\n<p>Implement the <code>/delete</code> route in <code>app.js</code>:</p>\n<pre><span class=\"c1\">// app.js</span>\n<span class=\"p\">...</span>\n\n<span class=\"c1\">// DELETE</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"k\">delete</span><span class=\"p\">(</span><span class=\"s1\">'/events/:id'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">models</span><span class=\"p\">.</span><span class=\"nx\">Event</span><span class=\"p\">.</span><span class=\"nx\">findByPk</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">id</span><span class=\"p\">).</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"nx\">event</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">event</span><span class=\"p\">.</span><span class=\"nx\">destroy</span><span class=\"p\">();</span>\n    <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">redirect</span><span class=\"p\">(</span><span class=\"sb\">`/`</span><span class=\"p\">);</span>\n  <span class=\"p\">}).</span><span class=\"k\">catch</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">);</span>\n  <span class=\"p\">});</span>\n<span class=\"p\">})</span>\n</pre>\n</div><p>Ok now manually test your destroy action.</p><p>We did it! All <strong>Resourceful Routes</strong> for the <code>Event</code> resource are complete!</p>"},{"id":"T0E6OlNlY3Rpb24tODM4Mw==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can destroy events'</span>\n$ git push\n</pre><p>But there is still one problem. All the event routes are all hanging out in the <code>app.js</code> file. This breaks the <strong>Separation of Concerns</strong> principle of clean and <strong>Good Smelling</strong> code. Let's pull out these routes into their own events <strong>Controller</strong>.</p>"},{"id":"T0E6OlNlY3Rpb24tODM4NA==","title":"Refactoring and Adding a Controller","htmlContent":"<div class=\"action\">\n<p></p>\n\n<p>First make a folder called <code>controllers</code>, now add the file <code>events.js</code> to this folder.</p>\n</div><p>Our <code>app.js</code> file is not aware that there is a controllers folder or a events controller yet. We have to connect them. There are basically two ways to connect this controller to our app:</p><ol>\n<li>We use the Express Router</li>\n<li>We use JavaScript's modules system</li>\n</ol><p>In this case we are going to use the JavaScript ES5 modules system both to introduce it and to avoid getting into the extra and &ndash; at this stage &ndash; unnecessary details of the Express Router.</p><p><code>require</code> can let you connect any file to any other in JavaScript. All you have to do is put <code>module.exports</code> into one file, and then <code>require(name-of-file)</code> in the other. Let's look at an example in our controller.</p><div class=\"action\">\n<p></p>\n\n<p>Take the <code>/index</code> function out from <code>app.js</code> and put it into the <code>controllers/events.js</code> file:</p>\n<pre><span class=\"c1\">//events.js</span>\n\n<span class=\"nx\">module</span><span class=\"p\">.</span><span class=\"nx\">exports</span> <span class=\"o\">=</span> <span class=\"kd\">function</span> <span class=\"p\">(</span><span class=\"nx\">app</span><span class=\"p\">,</span> <span class=\"nx\">models</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n\n    <span class=\"c1\">// INDEX</span>\n    <span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n        <span class=\"nx\">models</span><span class=\"p\">.</span><span class=\"nx\">Event</span><span class=\"p\">.</span><span class=\"nx\">findAll</span><span class=\"p\">({</span> <span class=\"nx\">order</span><span class=\"o\">:</span> <span class=\"p\">[[</span><span class=\"s1\">'createdAt'</span><span class=\"p\">,</span> <span class=\"s1\">'DESC'</span><span class=\"p\">]]</span> <span class=\"p\">}).</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"nx\">events</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n            <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'events-index'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">events</span><span class=\"o\">:</span> <span class=\"nx\">events</span> <span class=\"p\">});</span>\n        <span class=\"p\">})</span>\n    <span class=\"p\">})</span>\n<span class=\"p\">}</span>\n</pre>\n</div><p>Now let's import our events.js file into our app.js file. We'll pass the <code>app</code> and our model <code>Event</code> into the file as well.</p><div class=\"action\">\n<p></p>\n\n<p>Add the following <code>require</code> into <code>app.js</code>:</p>\n<pre><span class=\"c1\">// app.js</span>\n<span class=\"p\">...</span>\n\n<span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'./controllers/events'</span><span class=\"p\">)(</span><span class=\"nx\">app</span><span class=\"p\">,</span> <span class=\"nx\">models</span><span class=\"p\">);</span>\n</pre>\n</div><p>Manually test that you can still navigate to the <code>events-index</code> page.</p><p>Once you've done that, now we need to do the same for the rest of our routes.</p><div class=\"action\">\n<p></p>\n\n<p>Migrate the rest of the events routes into the <code>controllers/events.js</code> controller file from <code>app.js</code></p>\n</div><p>Make sure to test all of your functionality to insure that you didn't accidentally break something in the code migration!</p><p>Now we have a <code>views</code>, <code>controllers</code>, and a <code>db/models</code> folders, finally getting a clean <code>app.js</code> file and the proper separation of concerns!</p>"},{"id":"T0E6OlNlY3Rpb24tODM4NQ==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'proper separation of concerns'</span>\n$ git push\n</pre>"},{"id":"T0E6OlNlY3Rpb24tODM4Ng==","title":"Next Step - Pushing to Heroku","htmlContent":"<p>So now it is refactored and all working, let's get this site live by pushing to heroku ... let's work on that next!</p>"}]},"next":{"id":"T0E6OlBhZ2UtMTUyNw==","slug":"push-to-heroku-Dec=","title":"Push to Production with Heroku"},"previous":{"id":"T0E6OlBhZ2UtMTUyNw==","slug":"push-to-heroku-Dec=","title":"Push to Production with Heroku"}},{"id":"T0E6OlBhZ2UtMTUyNw==","title":"Push to Production with Heroku","slug":"push-to-heroku-Dec=","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tODI3MQ==","title":"Push to Production with Heroku","htmlContent":"<p>Time to ship some code! Since we've built and styled our Make Parties app, let's show it to the world by putting it online. We'll use a service called <a href=\"https://www.heroku.com\" target=\"_blank\">Heroku</a> that is free, but it does require a <strong>credit card</strong> to be on file.</p><h2>Resources</h2><p>It can be fairly common to get Heroku set up. If you run into trouble, here are some resources to help you along the way:</p><ul>\n<li><a href=\"https://devcenter.heroku.com/articles/error-codes\" target=\"_blank\">Heroku Error Codes</a></li>\n<li><a href=\"https://sequelize.readthedocs.io/en/1.7.0/articles/heroku/#running-migrations\" target=\"_blank\">Running Migrations on Heroku Using Sequelize</a></li>\n</ul><p>And don't forget the best resource: Googling your error!</p>"},{"id":"T0E6OlNlY3Rpb24tODI3Mg==","title":"Sign Up For and Install Heroku","htmlContent":"<div class=\"action\">\n<p></p>\n\n<p>First you need to create a Heroku account at <a href=\"https://www.heroku.com\" target=\"_blank\">heroku.com</a>.</p>\n</div><p>We will only be using free tools from Heroku, but to add free versions of specific add-on's, Heroku will require a credit card or debit card number.</p><p>Then you will need to add the Heroku Command Line Interface (CLI) to your bash terminal so we can interact with the Heroku service via the terminal and git.</p><h2>Cloud9</h2><div class=\"action\">\n<p></p>\n\n<p>In Cloud9 it is already installed but should be updated:</p>\n<pre>$ wget -O- https://toolbelt.heroku.com/install-ubuntu.sh <span class=\"p\">|</span> sh\n</pre>\n</div><h2>Your Computer</h2><div class=\"action\">\n<p></p>\n\n<p>In your computer you can install it with homebrew</p>\n<pre>$ brew install heroku/brew/heroku\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODI3Mw==","title":"Login to Heroku","htmlContent":"<div class=\"action\">\n<p></p>\n\n<p>Now login to heroku</p>\n<pre>$ heroku login -i\n</pre>\n</div><p>Now let's use the <code>heroku</code> command to create a heroku app and name it with \"make-parties\" and then our initials. So someone named Samantha Bee would be \"make-parties-sb\". This <code>heroku create</code> command will add our heroku app as a git remote repository that we will be able to push to using the git command <code>git push</code>. We can see our remote repos by using the command <code>git remote -v</code>.</p><div class=\"action\">\n<p></p>\n\n<p>Run the <code>heroku create</code> command:</p>\n<pre>$ heroku create make-parties-YOURINITIALS\n</pre>\n</div><p>Navigate your browser to <code>https://make-parties-YOURINITIALS.herokuapp.com</code> and see that there is an error there, and that it instructs you to run <code>heroku logs --tail</code>.</p><div class=\"action\">\n<p></p>\n\n<p>Run <code>heroku logs --tail</code> in your terminal:</p>\n<pre>$ heroku logs --tail\n</pre>\n</div><p>After running that command, you should see something like this:</p><pre><span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"ss\">T19</span><span class=\"p\">:</span><span class=\"mo\">07</span><span class=\"p\">:</span><span class=\"mi\">54</span><span class=\"o\">.</span><span class=\"mi\">989284</span><span class=\"o\">+</span><span class=\"mo\">00</span><span class=\"p\">:</span><span class=\"mo\">00</span> <span class=\"n\">app</span><span class=\"o\">[</span><span class=\"n\">api</span><span class=\"o\">]</span><span class=\"p\">:</span> <span class=\"no\">Release</span> <span class=\"n\">v1</span> <span class=\"n\">created</span> <span class=\"n\">by</span> <span class=\"n\">user</span> <span class=\"n\">ajbraus</span><span class=\"vi\">@gmail</span><span class=\"o\">.</span><span class=\"n\">com</span>\n<span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"ss\">T19</span><span class=\"p\">:</span><span class=\"mo\">07</span><span class=\"p\">:</span><span class=\"mi\">54</span><span class=\"o\">.</span><span class=\"mi\">989284</span><span class=\"o\">+</span><span class=\"mo\">00</span><span class=\"p\">:</span><span class=\"mo\">00</span> <span class=\"n\">app</span><span class=\"o\">[</span><span class=\"n\">api</span><span class=\"o\">]</span><span class=\"p\">:</span> <span class=\"no\">Initial</span> <span class=\"n\">release</span> <span class=\"n\">by</span> <span class=\"n\">user</span> <span class=\"n\">ajbraus</span><span class=\"vi\">@gmail</span><span class=\"o\">.</span><span class=\"n\">com</span>\n<span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"ss\">T19</span><span class=\"p\">:</span><span class=\"mo\">07</span><span class=\"p\">:</span><span class=\"mi\">55</span><span class=\"o\">.</span><span class=\"mi\">926176</span><span class=\"o\">+</span><span class=\"mo\">00</span><span class=\"p\">:</span><span class=\"mo\">00</span> <span class=\"n\">app</span><span class=\"o\">[</span><span class=\"n\">api</span><span class=\"o\">]</span><span class=\"p\">:</span> <span class=\"no\">Release</span> <span class=\"n\">v2</span> <span class=\"n\">created</span> <span class=\"n\">by</span> <span class=\"n\">user</span> <span class=\"n\">ajbraus</span><span class=\"vi\">@gmail</span><span class=\"o\">.</span><span class=\"n\">com</span>\n<span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"ss\">T19</span><span class=\"p\">:</span><span class=\"mo\">07</span><span class=\"p\">:</span><span class=\"mi\">55</span><span class=\"o\">.</span><span class=\"mi\">926176</span><span class=\"o\">+</span><span class=\"mo\">00</span><span class=\"p\">:</span><span class=\"mo\">00</span> <span class=\"n\">app</span><span class=\"o\">[</span><span class=\"n\">api</span><span class=\"o\">]</span><span class=\"p\">:</span> <span class=\"no\">Enable</span> <span class=\"no\">Logplex</span> <span class=\"n\">by</span> <span class=\"n\">user</span> <span class=\"n\">ajbraus</span><span class=\"vi\">@gmail</span><span class=\"o\">.</span><span class=\"n\">com</span>\n<span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"ss\">T19</span><span class=\"p\">:</span><span class=\"mi\">08</span><span class=\"p\">:</span><span class=\"mi\">56</span><span class=\"o\">.</span><span class=\"mi\">223988</span><span class=\"o\">+</span><span class=\"mo\">00</span><span class=\"p\">:</span><span class=\"mo\">00</span> <span class=\"n\">app</span><span class=\"o\">[</span><span class=\"n\">api</span><span class=\"o\">]</span><span class=\"p\">:</span> <span class=\"no\">Deploy</span> <span class=\"mi\">8477</span><span class=\"n\">ac80</span> <span class=\"n\">by</span> <span class=\"n\">user</span> <span class=\"n\">ajbraus</span><span class=\"vi\">@gmail</span><span class=\"o\">.</span><span class=\"n\">com</span>\n<span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"ss\">T19</span><span class=\"p\">:</span><span class=\"mi\">08</span><span class=\"p\">:</span><span class=\"mi\">56</span><span class=\"o\">.</span><span class=\"mi\">223988</span><span class=\"o\">+</span><span class=\"mo\">00</span><span class=\"p\">:</span><span class=\"mo\">00</span> <span class=\"n\">app</span><span class=\"o\">[</span><span class=\"n\">api</span><span class=\"o\">]</span><span class=\"p\">:</span> <span class=\"no\">Release</span> <span class=\"n\">v3</span> <span class=\"n\">created</span> <span class=\"n\">by</span> <span class=\"n\">user</span> <span class=\"n\">ajbraus</span><span class=\"vi\">@gmail</span><span class=\"o\">.</span><span class=\"n\">com</span>\n<span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"ss\">T19</span><span class=\"p\">:</span><span class=\"mi\">08</span><span class=\"p\">:</span><span class=\"mi\">56</span><span class=\"o\">.</span><span class=\"mi\">245417</span><span class=\"o\">+</span><span class=\"mo\">00</span><span class=\"p\">:</span><span class=\"mo\">00</span> <span class=\"n\">app</span><span class=\"o\">[</span><span class=\"n\">api</span><span class=\"o\">]</span><span class=\"p\">:</span> <span class=\"no\">Scaled</span> <span class=\"n\">to</span> <span class=\"n\">web</span><span class=\"err\">@</span><span class=\"mi\">1</span><span class=\"ss\">:Free</span> <span class=\"n\">by</span> <span class=\"n\">user</span> <span class=\"n\">ajbraus</span><span class=\"vi\">@gmail</span><span class=\"o\">.</span><span class=\"n\">com</span>\n<span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"ss\">T19</span><span class=\"p\">:</span><span class=\"mi\">08</span><span class=\"p\">:</span><span class=\"mi\">58</span><span class=\"o\">.</span><span class=\"mi\">822761</span><span class=\"o\">+</span><span class=\"mo\">00</span><span class=\"p\">:</span><span class=\"mo\">00</span> <span class=\"n\">heroku</span><span class=\"o\">[</span><span class=\"n\">web</span><span class=\"o\">.</span><span class=\"mi\">1</span><span class=\"o\">]</span><span class=\"p\">:</span> <span class=\"no\">Starting</span> <span class=\"n\">process</span> <span class=\"n\">with</span> <span class=\"n\">command</span> <span class=\"sb\">`npm start`</span>\n<span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"ss\">T19</span><span class=\"p\">:</span><span class=\"mi\">09</span><span class=\"p\">:</span><span class=\"mo\">02</span><span class=\"o\">.</span><span class=\"mi\">131028</span><span class=\"o\">+</span><span class=\"mo\">00</span><span class=\"p\">:</span><span class=\"mo\">00</span> <span class=\"n\">heroku</span><span class=\"o\">[</span><span class=\"n\">web</span><span class=\"o\">.</span><span class=\"mi\">1</span><span class=\"o\">]</span><span class=\"p\">:</span> <span class=\"no\">State</span> <span class=\"n\">changed</span> <span class=\"n\">from</span> <span class=\"n\">starting</span> <span class=\"n\">to</span> <span class=\"n\">crashed</span>\n<span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"ss\">T19</span><span class=\"p\">:</span><span class=\"mi\">09</span><span class=\"p\">:</span><span class=\"mo\">02</span><span class=\"o\">.</span><span class=\"mi\">136221</span><span class=\"o\">+</span><span class=\"mo\">00</span><span class=\"p\">:</span><span class=\"mo\">00</span> <span class=\"n\">heroku</span><span class=\"o\">[</span><span class=\"n\">web</span><span class=\"o\">.</span><span class=\"mi\">1</span><span class=\"o\">]</span><span class=\"p\">:</span> <span class=\"no\">State</span> <span class=\"n\">changed</span> <span class=\"n\">from</span> <span class=\"n\">crashed</span> <span class=\"n\">to</span> <span class=\"n\">starting</span>\n<span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"ss\">T19</span><span class=\"p\">:</span><span class=\"mi\">09</span><span class=\"p\">:</span><span class=\"mo\">02</span><span class=\"o\">.</span><span class=\"mi\">106945</span><span class=\"o\">+</span><span class=\"mo\">00</span><span class=\"p\">:</span><span class=\"mo\">00</span> <span class=\"n\">heroku</span><span class=\"o\">[</span><span class=\"n\">web</span><span class=\"o\">.</span><span class=\"mi\">1</span><span class=\"o\">]</span><span class=\"p\">:</span> <span class=\"no\">Process</span> <span class=\"n\">exited</span> <span class=\"n\">with</span> <span class=\"n\">status</span> <span class=\"mi\">1</span>\n<span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"ss\">T19</span><span class=\"p\">:</span><span class=\"mi\">09</span><span class=\"p\">:</span><span class=\"mo\">02</span><span class=\"o\">.</span><span class=\"mo\">0350</span><span class=\"mi\">80</span><span class=\"o\">+</span><span class=\"mo\">00</span><span class=\"p\">:</span><span class=\"mo\">00</span> <span class=\"n\">app</span><span class=\"o\">[</span><span class=\"n\">web</span><span class=\"o\">.</span><span class=\"mi\">1</span><span class=\"o\">]</span><span class=\"p\">:</span> <span class=\"n\">npm</span> <span class=\"no\">ERR</span><span class=\"o\">!</span> <span class=\"n\">missing</span> <span class=\"ss\">script</span><span class=\"p\">:</span> <span class=\"n\">start</span>\n<span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"ss\">T19</span><span class=\"p\">:</span><span class=\"mi\">09</span><span class=\"p\">:</span><span class=\"mo\">02</span><span class=\"o\">.</span><span class=\"mo\">0440</span><span class=\"mi\">94</span><span class=\"o\">+</span><span class=\"mo\">00</span><span class=\"p\">:</span><span class=\"mo\">00</span> <span class=\"n\">app</span><span class=\"o\">[</span><span class=\"n\">web</span><span class=\"o\">.</span><span class=\"mi\">1</span><span class=\"o\">]</span><span class=\"p\">:</span>\n<span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"ss\">T19</span><span class=\"p\">:</span><span class=\"mi\">09</span><span class=\"p\">:</span><span class=\"mo\">02</span><span class=\"o\">.</span><span class=\"mo\">044534</span><span class=\"o\">+</span><span class=\"mo\">00</span><span class=\"p\">:</span><span class=\"mo\">00</span> <span class=\"n\">app</span><span class=\"o\">[</span><span class=\"n\">web</span><span class=\"o\">.</span><span class=\"mi\">1</span><span class=\"o\">]</span><span class=\"p\">:</span> <span class=\"n\">npm</span> <span class=\"no\">ERR</span><span class=\"o\">!</span> <span class=\"n\">A</span> <span class=\"n\">complete</span> <span class=\"n\">log</span> <span class=\"n\">of</span> <span class=\"n\">this</span> <span class=\"n\">run</span> <span class=\"n\">can</span> <span class=\"n\">be</span> <span class=\"n\">found</span> <span class=\"k\">in</span><span class=\"p\">:</span>\n<span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"ss\">T19</span><span class=\"p\">:</span><span class=\"mi\">09</span><span class=\"p\">:</span><span class=\"mo\">02</span><span class=\"o\">.</span><span class=\"mo\">0446</span><span class=\"mi\">99</span><span class=\"o\">+</span><span class=\"mo\">00</span><span class=\"p\">:</span><span class=\"mo\">00</span> <span class=\"n\">app</span><span class=\"o\">[</span><span class=\"n\">web</span><span class=\"o\">.</span><span class=\"mi\">1</span><span class=\"o\">]</span><span class=\"p\">:</span> <span class=\"n\">npm</span> <span class=\"no\">ERR</span><span class=\"o\">!</span>     <span class=\"sr\">/app/</span><span class=\"o\">.</span><span class=\"n\">npm</span><span class=\"o\">/</span><span class=\"n\">_logs</span><span class=\"o\">/</span><span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"no\">T19_09_02_037Z</span><span class=\"o\">-</span><span class=\"n\">debug</span><span class=\"o\">.</span><span class=\"n\">log</span>\n<span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"ss\">T19</span><span class=\"p\">:</span><span class=\"mi\">09</span><span class=\"p\">:</span><span class=\"mo\">04</span><span class=\"o\">.</span><span class=\"mi\">679625</span><span class=\"o\">+</span><span class=\"mo\">00</span><span class=\"p\">:</span><span class=\"mo\">00</span> <span class=\"n\">heroku</span><span class=\"o\">[</span><span class=\"n\">web</span><span class=\"o\">.</span><span class=\"mi\">1</span><span class=\"o\">]</span><span class=\"p\">:</span> <span class=\"no\">Starting</span> <span class=\"n\">process</span> <span class=\"n\">with</span> <span class=\"n\">command</span> <span class=\"sb\">`npm start`</span>\n<span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"ss\">T19</span><span class=\"p\">:</span><span class=\"mi\">09</span><span class=\"p\">:</span><span class=\"mi\">08</span><span class=\"o\">.</span><span class=\"mi\">105133</span><span class=\"o\">+</span><span class=\"mo\">00</span><span class=\"p\">:</span><span class=\"mo\">00</span> <span class=\"n\">heroku</span><span class=\"o\">[</span><span class=\"n\">web</span><span class=\"o\">.</span><span class=\"mi\">1</span><span class=\"o\">]</span><span class=\"p\">:</span> <span class=\"no\">State</span> <span class=\"n\">changed</span> <span class=\"n\">from</span> <span class=\"n\">starting</span> <span class=\"n\">to</span> <span class=\"n\">crashed</span>\n<span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"ss\">T19</span><span class=\"p\">:</span><span class=\"mi\">09</span><span class=\"p\">:</span><span class=\"mi\">08</span><span class=\"o\">.</span><span class=\"mi\">083706</span><span class=\"o\">+</span><span class=\"mo\">00</span><span class=\"p\">:</span><span class=\"mo\">00</span> <span class=\"n\">heroku</span><span class=\"o\">[</span><span class=\"n\">web</span><span class=\"o\">.</span><span class=\"mi\">1</span><span class=\"o\">]</span><span class=\"p\">:</span> <span class=\"no\">Process</span> <span class=\"n\">exited</span> <span class=\"n\">with</span> <span class=\"n\">status</span> <span class=\"mi\">1</span>\n<span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"ss\">T19</span><span class=\"p\">:</span><span class=\"mi\">09</span><span class=\"p\">:</span><span class=\"mo\">07</span><span class=\"o\">.</span><span class=\"mi\">985068</span><span class=\"o\">+</span><span class=\"mo\">00</span><span class=\"p\">:</span><span class=\"mo\">00</span> <span class=\"n\">app</span><span class=\"o\">[</span><span class=\"n\">web</span><span class=\"o\">.</span><span class=\"mi\">1</span><span class=\"o\">]</span><span class=\"p\">:</span> <span class=\"n\">npm</span> <span class=\"no\">ERR</span><span class=\"o\">!</span> <span class=\"n\">missing</span> <span class=\"ss\">script</span><span class=\"p\">:</span> <span class=\"n\">start</span>\n<span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"ss\">T19</span><span class=\"p\">:</span><span class=\"mi\">09</span><span class=\"p\">:</span><span class=\"mi\">08</span><span class=\"o\">.</span><span class=\"mo\">015</span><span class=\"mi\">827</span><span class=\"o\">+</span><span class=\"mo\">00</span><span class=\"p\">:</span><span class=\"mo\">00</span> <span class=\"n\">app</span><span class=\"o\">[</span><span class=\"n\">web</span><span class=\"o\">.</span><span class=\"mi\">1</span><span class=\"o\">]</span><span class=\"p\">:</span>\n<span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"ss\">T19</span><span class=\"p\">:</span><span class=\"mi\">09</span><span class=\"p\">:</span><span class=\"mi\">08</span><span class=\"o\">.</span><span class=\"mo\">016</span><span class=\"mi\">884</span><span class=\"o\">+</span><span class=\"mo\">00</span><span class=\"p\">:</span><span class=\"mo\">00</span> <span class=\"n\">app</span><span class=\"o\">[</span><span class=\"n\">web</span><span class=\"o\">.</span><span class=\"mi\">1</span><span class=\"o\">]</span><span class=\"p\">:</span> <span class=\"n\">npm</span> <span class=\"no\">ERR</span><span class=\"o\">!</span> <span class=\"n\">A</span> <span class=\"n\">complete</span> <span class=\"n\">log</span> <span class=\"n\">of</span> <span class=\"n\">this</span> <span class=\"n\">run</span> <span class=\"n\">can</span> <span class=\"n\">be</span> <span class=\"n\">found</span> <span class=\"k\">in</span><span class=\"p\">:</span>\n<span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"ss\">T19</span><span class=\"p\">:</span><span class=\"mi\">09</span><span class=\"p\">:</span><span class=\"mi\">08</span><span class=\"o\">.</span><span class=\"mo\">017337</span><span class=\"o\">+</span><span class=\"mo\">00</span><span class=\"p\">:</span><span class=\"mo\">00</span> <span class=\"n\">app</span><span class=\"o\">[</span><span class=\"n\">web</span><span class=\"o\">.</span><span class=\"mi\">1</span><span class=\"o\">]</span><span class=\"p\">:</span> <span class=\"n\">npm</span> <span class=\"no\">ERR</span><span class=\"o\">!</span>     <span class=\"sr\">/app/</span><span class=\"o\">.</span><span class=\"n\">npm</span><span class=\"o\">/</span><span class=\"n\">_logs</span><span class=\"o\">/</span><span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"no\">T19_09_07_997Z</span><span class=\"o\">-</span><span class=\"n\">debug</span><span class=\"o\">.</span><span class=\"n\">log</span>\n<span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"ss\">T19</span><span class=\"p\">:</span><span class=\"mi\">09</span><span class=\"p\">:</span><span class=\"mi\">10</span><span class=\"o\">.</span><span class=\"mi\">316856</span><span class=\"o\">+</span><span class=\"mo\">00</span><span class=\"p\">:</span><span class=\"mo\">00</span> <span class=\"n\">heroku</span><span class=\"o\">[</span><span class=\"n\">router</span><span class=\"o\">]</span><span class=\"p\">:</span> <span class=\"n\">at</span><span class=\"o\">=</span><span class=\"n\">error</span> <span class=\"n\">code</span><span class=\"o\">=</span><span class=\"no\">H10</span> <span class=\"n\">desc</span><span class=\"o\">=</span><span class=\"s2\">\"App crashed\"</span> <span class=\"nb\">method</span><span class=\"o\">=</span><span class=\"no\">GET</span> <span class=\"n\">path</span><span class=\"o\">=</span><span class=\"s2\">\"/\"</span> <span class=\"n\">host</span><span class=\"o\">=</span><span class=\"n\">make</span><span class=\"o\">-</span><span class=\"n\">parties</span><span class=\"o\">-</span><span class=\"n\">ajb</span><span class=\"o\">.</span><span class=\"n\">herokuapp</span><span class=\"o\">.</span><span class=\"n\">com</span> <span class=\"n\">request_id</span><span class=\"o\">=</span><span class=\"n\">e2405128</span><span class=\"o\">-</span><span class=\"mi\">55</span><span class=\"n\">ee</span><span class=\"o\">-</span><span class=\"mi\">4</span><span class=\"n\">c0a</span><span class=\"o\">-</span><span class=\"n\">b447</span><span class=\"o\">-</span><span class=\"mi\">184</span><span class=\"n\">d879f900a</span> <span class=\"n\">fwd</span><span class=\"o\">=</span><span class=\"s2\">\"104.197.64.166\"</span> <span class=\"n\">dyno</span><span class=\"o\">=</span> <span class=\"n\">connect</span><span class=\"o\">=</span> <span class=\"n\">service</span><span class=\"o\">=</span> <span class=\"n\">status</span><span class=\"o\">=</span><span class=\"mi\">503</span> <span class=\"n\">bytes</span><span class=\"o\">=</span> <span class=\"n\">protocol</span><span class=\"o\">=</span><span class=\"n\">https</span>\n<span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"ss\">T19</span><span class=\"p\">:</span><span class=\"mi\">13</span><span class=\"p\">:</span><span class=\"mi\">56</span><span class=\"o\">.</span><span class=\"mi\">767347</span><span class=\"o\">+</span><span class=\"mo\">00</span><span class=\"p\">:</span><span class=\"mo\">00</span> <span class=\"n\">heroku</span><span class=\"o\">[</span><span class=\"n\">router</span><span class=\"o\">]</span><span class=\"p\">:</span> <span class=\"n\">at</span><span class=\"o\">=</span><span class=\"n\">error</span> <span class=\"n\">code</span><span class=\"o\">=</span><span class=\"no\">H10</span> <span class=\"n\">desc</span><span class=\"o\">=</span><span class=\"s2\">\"App crashed\"</span> <span class=\"nb\">method</span><span class=\"o\">=</span><span class=\"no\">GET</span> <span class=\"n\">path</span><span class=\"o\">=</span><span class=\"s2\">\"/\"</span> <span class=\"n\">host</span><span class=\"o\">=</span><span class=\"n\">make</span><span class=\"o\">-</span><span class=\"n\">parties</span><span class=\"o\">-</span><span class=\"n\">ajb</span><span class=\"o\">.</span><span class=\"n\">herokuapp</span><span class=\"o\">.</span><span class=\"n\">com</span> <span class=\"n\">request_id</span><span class=\"o\">=</span><span class=\"n\">a543045a</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"n\">d7e</span><span class=\"o\">-</span><span class=\"mi\">497</span><span class=\"n\">f</span><span class=\"o\">-</span><span class=\"n\">b2cd</span><span class=\"o\">-</span><span class=\"n\">ef49095b4c9a</span> <span class=\"n\">fwd</span><span class=\"o\">=</span><span class=\"s2\">\"142.254.99.26\"</span> <span class=\"n\">dyno</span><span class=\"o\">=</span> <span class=\"n\">connect</span><span class=\"o\">=</span> <span class=\"n\">service</span><span class=\"o\">=</span> <span class=\"n\">status</span><span class=\"o\">=</span><span class=\"mi\">503</span> <span class=\"n\">bytes</span><span class=\"o\">=</span> <span class=\"n\">protocol</span><span class=\"o\">=</span><span class=\"n\">https</span>\n<span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"ss\">T19</span><span class=\"p\">:</span><span class=\"mi\">13</span><span class=\"p\">:</span><span class=\"mi\">57</span><span class=\"o\">.</span><span class=\"mi\">468424</span><span class=\"o\">+</span><span class=\"mo\">00</span><span class=\"p\">:</span><span class=\"mo\">00</span> <span class=\"n\">heroku</span><span class=\"o\">[</span><span class=\"n\">router</span><span class=\"o\">]</span><span class=\"p\">:</span> <span class=\"n\">at</span><span class=\"o\">=</span><span class=\"n\">error</span> <span class=\"n\">code</span><span class=\"o\">=</span><span class=\"no\">H10</span> <span class=\"n\">desc</span><span class=\"o\">=</span><span class=\"s2\">\"App crashed\"</span> <span class=\"nb\">method</span><span class=\"o\">=</span><span class=\"no\">GET</span> <span class=\"n\">path</span><span class=\"o\">=</span><span class=\"s2\">\"/favicon.ico\"</span> <span class=\"n\">host</span><span class=\"o\">=</span><span class=\"n\">make</span><span class=\"o\">-</span><span class=\"n\">parties</span><span class=\"o\">-</span><span class=\"n\">ajb</span><span class=\"o\">.</span><span class=\"n\">herokuapp</span><span class=\"o\">.</span><span class=\"n\">com</span> <span class=\"n\">request_id</span><span class=\"o\">=</span><span class=\"mi\">339</span><span class=\"n\">b35a7</span><span class=\"o\">-</span><span class=\"mi\">399</span><span class=\"n\">d</span><span class=\"o\">-</span><span class=\"mi\">4420</span><span class=\"o\">-</span><span class=\"mi\">822</span><span class=\"n\">c</span><span class=\"o\">-</span><span class=\"n\">faaa3d328fb2</span> <span class=\"n\">fwd</span><span class=\"o\">=</span><span class=\"s2\">\"142.254.99.26\"</span> <span class=\"n\">dyno</span><span class=\"o\">=</span> <span class=\"n\">connect</span><span class=\"o\">=</span> <span class=\"n\">service</span><span class=\"o\">=</span> <span class=\"n\">status</span><span class=\"o\">=</span><span class=\"mi\">503</span> <span class=\"n\">bytes</span><span class=\"o\">=</span> <span class=\"n\">protocol</span><span class=\"o\">=</span><span class=\"n\">https</span>\n<span class=\"o\">^</span><span class=\"n\">C</span>\n</pre><p>The important line here is in the middle:</p><pre><span class=\"mi\">2018</span><span class=\"o\">-</span><span class=\"mi\">12</span><span class=\"o\">-</span><span class=\"mi\">14</span><span class=\"ss\">T19</span><span class=\"p\">:</span><span class=\"mi\">09</span><span class=\"p\">:</span><span class=\"mo\">02</span><span class=\"o\">.</span><span class=\"mo\">0350</span><span class=\"mi\">80</span><span class=\"o\">+</span><span class=\"mo\">00</span><span class=\"p\">:</span><span class=\"mo\">00</span> <span class=\"n\">app</span><span class=\"o\">[</span><span class=\"n\">web</span><span class=\"o\">.</span><span class=\"mi\">1</span><span class=\"o\">]</span><span class=\"p\">:</span> <span class=\"n\">npm</span> <span class=\"no\">ERR</span><span class=\"o\">!</span> <span class=\"n\">missing</span> <span class=\"ss\">script</span><span class=\"p\">:</span> <span class=\"n\">start</span>\n</pre><p>Heroku requires a start script. So we're going to add that through our <code>package.json</code> file.</p><div class=\"info\">\n<p></p>\n\n<p>Even if you don't receive any of these errors, it's important to still follow these steps so that your setup for heroku is correct.</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODI3NA==","title":"Adding Your Procfile","htmlContent":"<p>Heroku calls <code>npm start</code> when it starts an node project. So you have to define that script in the <code>package.json</code> file.</p><div class=\"action\">\n<p></p>\n\n<p>Open <code>package.json</code> and add the following \"start\" script to it:</p>\n<pre><span class=\"err\">...</span>\n  <span class=\"s2\">\"scripts\"</span><span class=\"err\">:</span> <span class=\"p\">{</span>\n    <span class=\"nt\">\"start\"</span><span class=\"p\">:</span> <span class=\"s2\">\"node app.js\"</span><span class=\"p\">,</span>\n    <span class=\"nt\">\"test\"</span><span class=\"p\">:</span> <span class=\"s2\">\"echo \\\"Error: no test specified\\\" &amp;&amp; exit 1\"</span>\n  <span class=\"p\">}</span><span class=\"err\">,</span>\n<span class=\"err\">...</span>\n</pre>\n</div><p>Alright, now we can add and commit and push our code to heroku and open our new website.</p><div class=\"action\">\n<p></p>\n\n<p>Follow the usual commit steps, but this time we'll push to <code>heroku master</code>:</p>\n<pre>$ git add .\n$ git commit -m <span class=\"s1\">'adding start script'</span>\n$ git push heroku master\n</pre>\n</div><p>Navigate your browser to <code>https://make-parties-YOURINITIALS.herokuapp.com</code>. You are probably seeing an error screen right now! Bit of a let down maybe. But also a good lesson - <strong>Things never work the first time</strong>. Let's debug our issues.</p>"},{"id":"T0E6OlNlY3Rpb24tODI3NQ==","title":"Adding a Production Database","htmlContent":"<p>It looks like the error is that we cannot connect to our PostgreSQL database. That's because it is looking at our <code>db/config/config.json</code> file and then at the <code>production</code> option, and then looking for the <code>PROD_DATABASE_URL</code> URI, but that is not defined on Heroku. So we have to add a PostgreSQL database to Heroku using an add-on called <a href=\"https://elements.heroku.com/addons/heroku-postgresql\" target=\"_blank\">Heroku Postgres</a>.</p><div class=\"action\">\n<p></p>\n\n<p>Add Heroku Postgres:</p>\n<pre>$ heroku addons:create heroku-postgresql:hobby-dev\n</pre>\n</div><p>We will still have problems though because we need to update our <code>config.json</code>.</p><div class=\"action\">\n<p></p>\n\n<p>Update <code>db/config/config.json</code> to have the following in the <code>production</code> section:</p>\n<pre> <span class=\"err\">...</span>\n <span class=\"s2\">\"production\"</span><span class=\"err\">:</span> <span class=\"p\">{</span>\n   <span class=\"nt\">\"use_env_variable\"</span><span class=\"p\">:</span> <span class=\"s2\">\"DATABASE_URL\"</span><span class=\"p\">,</span>\n   <span class=\"nt\">\"dialect\"</span><span class=\"p\">:</span> <span class=\"s2\">\"postgres\"</span><span class=\"p\">,</span>\n   <span class=\"nt\">\"dialectOptions\"</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n      <span class=\"nt\">\"ssl\"</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"nt\">\"require\"</span><span class=\"p\">:</span> <span class=\"kc\">true</span><span class=\"p\">,</span>\n        <span class=\"nt\">\"rejectUnauthorized\"</span><span class=\"p\">:</span> <span class=\"kc\">false</span>\n      <span class=\"p\">}</span>\n    <span class=\"p\">}</span>\n  <span class=\"p\">}</span>\n</pre>\n</div><p>We also need to add a Heroku config variable to mark that we are in production:</p><div class=\"action\">\n<p></p>\n\n<p>Add a Heroku config variable</p>\n<pre>$ heroku config:set <span class=\"nv\">NODE_ENV</span><span class=\"o\">=</span>production\n</pre>\n</div><p>Let's get our code onto Heroku now:</p><div class=\"action\">\n<p></p>\n\n<p>Push up to Heroku:</p>\n<pre>$ git add .\n$ git commit -m <span class=\"s2\">\"pushing heroku config info\"</span>\n$ git push heroku master\n</pre>\n</div><p>Finally, we need run our migrations onto Heroku as well before anything will work properly!</p><div class=\"action\">\n<p></p>\n\n<p>Run the following commands for the migration:</p>\n<pre>$ heroku run bash\n$ sequelize -m <span class=\"c1\"># this just makes sure sequelize is installed</span>\n$ sequelize db:migrate\n</pre>\n</div><p>Ok now our database should connect, and we can navigate around our Heroku site!</p>"},{"id":"T0E6OlNlY3Rpb24tODI3Ng==","title":"WooHoo!","htmlContent":"<p>If everything went well, you should be able to navigate to your Heroku site and see a blank version of our app:</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P08-Push-to-Heroku/assets/heroku-live.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P08-Push-to-Heroku/assets/heroku-live.png\" alt=\"heroku-live\" title=\"\">\n        </a></p><p>Awwww yeah - you did it! You made your first RESTful and Resourceful app using Node.js, Express.js, and PostgreSQL! V1 is done and shipped!</p>"}]},"next":{"id":"T0E6OlBhZ2UtMTUyOA==","slug":"adding-rsvps","title":"Adding Rsvps (Form)"},"previous":{"id":"T0E6OlBhZ2UtMTUyOA==","slug":"adding-rsvps","title":"Adding Rsvps (Form)"}},{"id":"T0E6OlBhZ2UtMTUyOA==","title":"Adding Rsvps (Form)","slug":"adding-rsvps","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tODI3Nw==","title":"Adding Rsvps (Form)","htmlContent":"<p>Let's not forget about our <strong>User Stories</strong></p><ol>\n<li><del>Users can view all events (index)</del></li>\n<li><del>Users can create a event (new/create)</del></li>\n<li><del>Users can view one event (show)</del></li>\n<li><del>Users can edit a event (edit/update)</del></li>\n<li><del>Users can delete a event (destroy)</del></li>\n<li><strong>Users can rsvp to events (/rsvps/create, /rsvps/new)</strong></li>\n<li>Users can cancel their rsvp (/rsvps/destroy)</li>\n</ol><p>At this point you should have a functioning site that creates and saves Events to a database. This system manages a <em>single resource</em>, which we've called a 'Event'. In this section you will add a new resource which will represent Rsvps or reservations to events. We'll call this resource \"Rsvps\" because \"reservations\" is very long and annoying to type and can increase the chance of typos.</p><p>Rsvps will be treated like Events. They will have a model that defines them, and they will have a table in the database.</p><p>Events will \"Have Many\" Rsvps and Rspvs will \"Belong To\" Events. And they will have two attributes: <code>name</code> and <code>email</code>.</p>"},{"id":"T0E6OlNlY3Rpb24tODI3OA==","title":"Make the Rsvp Button & rsvps-new Form","htmlContent":"<p>Follow the same approach used in the tutorial, start with what users will see. Users looking at an Event may want to rsvp see who has already rsvp'd. Adding rsvps will require a button and then an <code>rspvs-new</code> form template to create the rsvp.</p><div class=\"action\">\n<p></p>\n\n<p>Let's add an rsvp column on the right. First remove the <code>offset-lg-3</code> class on the events column, and then add a button for RSVPS:</p>\n<pre><span class=\"c\">&lt;!-- views/events-show.handlebars --&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"row mt-4\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"col-lg-6\"</span><span class=\"p\">&gt;</span>\n    ...\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"col-lg-4 offset-lg-1\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/events/{{event.id}}/rsvps/new\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"btn btn-primary btn-sm\"</span><span class=\"p\">&gt;</span>RSVP<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODI3OQ==","title":"Create A Rsvps New Template","htmlContent":"<p>Continuing with <strong>Resourceful Routing</strong> we're going to be as resourceful as we can in building our Rsvps. We aren't going to do all seven routes, just three. And notice that these are <strong>Nested Routes</strong> under their parent event:</p><table>\n<thead>\n<tr>\n<th>URL</th>\n<th>HTTP Verb</th>\n<th>Action</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>/events/:eventId/rsvps/new</td>\n<td>GET</td>\n<td>new</td>\n</tr>\n<tr>\n<td>/events/:eventId/rsvps</td>\n<td>POST</td>\n<td>create</td>\n</tr>\n<tr>\n<td>/events/:eventId/rsvps/:id</td>\n<td>DELETE</td>\n<td>Destroy</td>\n</tr>\n</tbody>\n</table><p>So let's start by adding a new controller:</p><div class=\"action\">\n<p></p>\n\n<p>Create <code>/controllers/rsvps.js</code> and add the following code:</p>\n<pre><span class=\"c1\">// controllers/rsvps.js</span>\n\n<span class=\"nx\">module</span><span class=\"p\">.</span><span class=\"nx\">exports</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"nx\">app</span><span class=\"p\">,</span> <span class=\"nx\">models</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// NEW</span>\n  <span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/events/:eventId/rsvps/new'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">models</span><span class=\"p\">.</span><span class=\"nx\">Event</span><span class=\"p\">.</span><span class=\"nx\">findByPk</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">eventId</span><span class=\"p\">).</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"nx\">event</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'rsvps-new'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">event</span><span class=\"o\">:</span> <span class=\"nx\">event</span> <span class=\"p\">});</span>\n    <span class=\"p\">});</span>\n  <span class=\"p\">});</span>\n\n  <span class=\"c1\">// CREATE</span>\n\n  <span class=\"c1\">// DESTROY  </span>\n<span class=\"p\">}</span>\n</pre>\n</div><p>And remember to require this in your <code>app.js</code> next to your other controller</p><div class=\"action\">\n<p></p>\n\n<p>Require the new controller in <code>app.js</code>:</p>\n<pre><span class=\"c1\">// app.js</span>\n\n<span class=\"p\">...</span>\n<span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'./controllers/events'</span><span class=\"p\">)(</span><span class=\"nx\">app</span><span class=\"p\">,</span> <span class=\"nx\">models</span><span class=\"p\">);</span>\n<span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"s1\">'./controllers/rsvps'</span><span class=\"p\">)(</span><span class=\"nx\">app</span><span class=\"p\">,</span> <span class=\"nx\">models</span><span class=\"p\">);</span>\n</pre>\n</div><p>Now you can navigate to your rsvps new template using the button...but we still need to make the template!</p>"},{"id":"T0E6OlNlY3Rpb24tODI4MA==","title":"New Rsvp Template","htmlContent":"<div class=\"action\">\n<p></p>\n\n<p>Let's make our <code>views/rsvps-new.handlebars</code> template:</p>\n<pre><span class=\"c\">&lt;!-- views/rsvp-new.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"row mt-4\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"col-lg-6 offset-lg-3\"</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"card\"</span><span class=\"p\">&gt;</span>\n            <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"card-body\"</span><span class=\"p\">&gt;</span>\n                <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"card-title\"</span><span class=\"p\">&gt;</span>\n                    <span class=\"p\">&lt;</span><span class=\"nt\">h3</span><span class=\"p\">&gt;</span>New RSVP<span class=\"p\">&lt;/</span><span class=\"nt\">h3</span><span class=\"p\">&gt;</span>\n                    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"lead\"</span><span class=\"p\">&gt;</span>\n                        Event: {{event.title}}\n                    <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n                <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n                <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"card-text\"</span><span class=\"p\">&gt;</span>\n                    <span class=\"p\">&lt;</span><span class=\"nt\">form</span> <span class=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">\"/events/{{event.id}}/rsvps\"</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">\"post\"</span><span class=\"p\">&gt;</span>\n                        <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-group\"</span><span class=\"p\">&gt;</span>\n                            <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"title\"</span><span class=\"p\">&gt;</span>Name<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;</span>\n                            <span class=\"p\">&lt;</span><span class=\"nt\">input</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"name\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-control\"</span> <span class=\"na\">placeholder</span><span class=\"o\">=</span><span class=\"s\">\"Jane Doe\"</span> <span class=\"p\">/&gt;</span>\n                        <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n                        <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-group\"</span><span class=\"p\">&gt;</span>\n                            <span class=\"p\">&lt;</span><span class=\"nt\">label</span> <span class=\"na\">for</span><span class=\"o\">=</span><span class=\"s\">\"title\"</span><span class=\"p\">&gt;</span>Email<span class=\"p\">&lt;/</span><span class=\"nt\">label</span><span class=\"p\">&gt;</span>\n                            <span class=\"p\">&lt;</span><span class=\"nt\">input</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"email\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-control\"</span> <span class=\"na\">placeholder</span><span class=\"o\">=</span><span class=\"s\">\"Jane.Doe@gmail.com\"</span> <span class=\"p\">/&gt;</span>\n                        <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n                        <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"text-right\"</span><span class=\"p\">&gt;</span>\n                            <span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">'text-muted mr-2'</span><span class=\"p\">&gt;</span>Cancel<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n                            <span class=\"p\">&lt;</span><span class=\"nt\">button</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"submit\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"btn btn-primary\"</span> <span class=\"na\">name</span><span class=\"o\">=</span><span class=\"s\">\"button\"</span><span class=\"p\">&gt;</span>Save<span class=\"p\">&lt;/</span><span class=\"nt\">button</span><span class=\"p\">&gt;</span>\n                        <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n                    <span class=\"p\">&lt;/</span><span class=\"nt\">form</span><span class=\"p\">&gt;</span>\n                <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n            <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>Notice you used the same class names and markup used in the Events form. This form only has three form elements. One input for the name of the rsvp, one for email, and a button to submit the form.</p><p>Try clicking submit. Uh-oh! No create route (but we expected that!).</p>"},{"id":"T0E6OlNlY3Rpb24tODI4MQ==","title":"Creating the Rsvp","htmlContent":"<p>Now we want to setup our rsvps create action so we have somewhere to submit our form to:</p><div class=\"action\">\n<p></p>\n\n<p>Add a <code>/create</code> route in <code>controllers/rsvps.js</code>:</p>\n<pre><span class=\"c1\">// controllers/rsvps.js</span>\n\n<span class=\"p\">...</span>\n\n<span class=\"c1\">// CREATE</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">post</span><span class=\"p\">(</span><span class=\"s1\">'/events/:eventId/rsvps'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">models</span><span class=\"p\">.</span><span class=\"nx\">Rsvp</span><span class=\"p\">.</span><span class=\"nx\">create</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">body</span><span class=\"p\">).</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"nx\">rsvp</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n        <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">redirect</span><span class=\"p\">(</span><span class=\"sb\">`/events/</span><span class=\"si\">${</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">eventId</span><span class=\"si\">}</span><span class=\"sb\">`</span><span class=\"p\">);</span>\n    <span class=\"p\">}).</span><span class=\"k\">catch</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n        <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">)</span>\n    <span class=\"p\">});</span>\n<span class=\"p\">});</span>\n</pre>\n</div><p>If you try to run this (go ahead!), we'll see that this won't work yet because our next step is create a model and SQL db table for rsvps.</p>"},{"id":"T0E6OlNlY3Rpb24tODI4Mg==","title":"Adding an Rsvp Model","htmlContent":"<p>Much like we did for Events, let's create the model and migration for rsvps:</p><div class=\"action\">\n<p></p>\n\n<p>Create a new RSVP model using sequelize:</p>\n<pre>$ sequelize model:create --name Rsvp --attributes name:string,email:string\n</pre>\n</div><p>Now we need to run the migration:</p><div class=\"action\">\n<p></p>\n\n<p>Run the migration:</p>\n<pre>$ sequelize db:migrate\n</pre>\n</div><p>This creates a model with a <code>name</code> and <code>email</code> attributes, but no association to the parent Event. If we want these two resources to be associated, then we'll need to associate their tables at the database level.</p>"},{"id":"T0E6OlNlY3Rpb24tODI4Mw==","title":"Adding an EventId attribute to Rsvps","htmlContent":"<p>Remember that Rsvps \"Belong To\" Events, and Events \"Have Many\" Rsvps. This is called a <strong>One-To-Many Association</strong>. To establish this we need to add an attribute called <code>EventId</code> to the rsvp table.</p><p>Sequelize does not have any easy way to do this via migrations, so we are going to do this the hard way.</p><div class=\"action\">\n<p></p>\n\n<p>First make a custom migration using the sequelize generator:</p>\n<pre>$ sequelize migration:create --name add-event-id-to-rsvps\n</pre>\n</div><p>Now in the migration, let's add the EventId column then we are going to change the <code>EventId</code> column we just created to become a <strong>Foreign Key</strong>&mdash;the column that associates one table with another.</p><div class=\"action\">\n<p></p>\n\n<p>Update the new <code>db/migrations/add-event-id-to-rsvps.js</code> migration file to the following:</p>\n<pre><span class=\"c1\">// migration</span>\n\n<span class=\"s1\">'use strict'</span><span class=\"p\">;</span>\n\n<span class=\"nx\">module</span><span class=\"p\">.</span><span class=\"nx\">exports</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n  <span class=\"nx\">up</span><span class=\"o\">:</span> <span class=\"p\">(</span><span class=\"nx\">queryInterface</span><span class=\"p\">,</span> <span class=\"nx\">Sequelize</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"k\">return</span> <span class=\"nx\">queryInterface</span><span class=\"p\">.</span><span class=\"nx\">addColumn</span><span class=\"p\">(</span>\n      <span class=\"s1\">'Rsvps'</span><span class=\"p\">,</span> <span class=\"c1\">// name of source model</span>\n      <span class=\"s1\">'EventId'</span><span class=\"p\">,</span> <span class=\"c1\">// name of key we are adding</span>\n      <span class=\"p\">{</span> \n        <span class=\"nx\">type</span><span class=\"o\">:</span> <span class=\"nx\">Sequelize</span><span class=\"p\">.</span><span class=\"nx\">INTEGER</span><span class=\"p\">,</span>\n        <span class=\"nx\">references</span><span class=\"o\">:</span> <span class=\"p\">{</span> <span class=\"c1\">//Required field</span>\n          <span class=\"nx\">model</span><span class=\"o\">:</span> <span class=\"s1\">'Events'</span><span class=\"p\">,</span>\n          <span class=\"nx\">key</span><span class=\"o\">:</span> <span class=\"s1\">'id'</span>\n        <span class=\"p\">},</span>\n        <span class=\"nx\">onDelete</span><span class=\"o\">:</span> <span class=\"s1\">'CASCADE'</span><span class=\"p\">,</span>\n        <span class=\"nx\">onUpdate</span><span class=\"o\">:</span> <span class=\"s1\">'CASCADE'</span>\n      <span class=\"p\">}</span>\n    <span class=\"p\">);</span>\n  <span class=\"p\">},</span>\n\n  <span class=\"nx\">down</span><span class=\"o\">:</span> <span class=\"p\">(</span><span class=\"nx\">queryInterface</span><span class=\"p\">,</span> <span class=\"nx\">Sequelize</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"k\">return</span> <span class=\"nx\">queryInterface</span><span class=\"p\">.</span><span class=\"nx\">removeColumn</span><span class=\"p\">(</span><span class=\"s1\">'Rsvps'</span><span class=\"p\">,</span> <span class=\"s1\">'EventId'</span><span class=\"p\">);</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">};</span>\n</pre>\n</div><p>We'll also need to update the Rsvp and Event models to define the \"has many\" and \"belongs to\" association:</p><div class=\"action\">\n<p></p>\n\n<p>Update the following models to accurately reflect the associations:</p>\n\n<p><strong>db/models/rsvp.js</strong></p>\n<pre><span class=\"c1\">// db/models/rsvp.js</span>\n<span class=\"p\">...</span>\n  <span class=\"nx\">Rsvp</span><span class=\"p\">.</span><span class=\"nx\">associate</span> <span class=\"o\">=</span> <span class=\"kd\">function</span><span class=\"p\">(</span><span class=\"nx\">models</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"nx\">Rsvp</span><span class=\"p\">.</span><span class=\"nx\">belongsTo</span><span class=\"p\">(</span><span class=\"nx\">models</span><span class=\"p\">.</span><span class=\"nx\">Event</span><span class=\"p\">);</span> <span class=\"c1\">// EventId</span>\n  <span class=\"p\">};</span>\n</pre>\n<p><strong>db/models/event.js</strong></p>\n<pre><span class=\"c1\">// db/models/event.js</span>\n<span class=\"p\">...</span>\n  <span class=\"nx\">Event</span><span class=\"p\">.</span><span class=\"nx\">associate</span> <span class=\"o\">=</span> <span class=\"kd\">function</span><span class=\"p\">(</span><span class=\"nx\">models</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"nx\">Event</span><span class=\"p\">.</span><span class=\"nx\">hasMany</span><span class=\"p\">(</span><span class=\"nx\">models</span><span class=\"p\">.</span><span class=\"nx\">Rsvp</span><span class=\"p\">);</span>\n  <span class=\"p\">};</span>\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODI4NA==","title":"Setting the EventId","htmlContent":"<p>Now we need to make sure the <code>EventId</code> attribute is set upon creation of an rsvp. We'll do this by updating the <code>req.body</code> object before creating the rsvp.</p><div class=\"action\">\n<p></p>\n\n<p>Update the <code>/create</code> route in <code>controllers/rsvps.js</code> to the following:</p>\n<pre><span class=\"c1\">// controllers/rsvps.js</span>\n<span class=\"p\">...</span>\n\n  <span class=\"c1\">// CREATE</span>\n  <span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">post</span><span class=\"p\">(</span><span class=\"s1\">'/events/:eventId/rsvps'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">body</span><span class=\"p\">.</span><span class=\"nx\">EventId</span> <span class=\"o\">=</span> <span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">eventId</span><span class=\"p\">;</span>\n    <span class=\"nx\">models</span><span class=\"p\">.</span><span class=\"nx\">Rsvp</span><span class=\"p\">.</span><span class=\"nx\">create</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">body</span><span class=\"p\">).</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"nx\">rsvp</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">redirect</span><span class=\"p\">(</span><span class=\"sb\">`/events/</span><span class=\"si\">${</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">eventId</span><span class=\"si\">}</span><span class=\"sb\">`</span><span class=\"p\">);</span>\n    <span class=\"p\">}).</span><span class=\"k\">catch</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n        <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">)</span>\n    <span class=\"p\">});</span>\n  <span class=\"p\">});</span>\n</pre>\n</div><p>Last step before we can save rsvps is we need to actually run the migration we created!</p><div class=\"action\">\n<p></p>\n\n<p>Run the migration!</p>\n<pre>$ sequelize db:migrate\n</pre>\n</div><p>When you save the Rsvp, it should be setting the <code>EventId</code> attribute now to the parent event instance. That's good because we'll use that association in our queries going forward.</p><p>Test this out yourself:</p><ul>\n<li>Create an RSVP for an event</li>\n<li>Check your DB (using Postico, terminal, etc.) and make sure there is an RSVP table, and you see your rsvp in it</li>\n</ul>"},{"id":"T0E6OlNlY3Rpb24tODI4NQ==","title":"Fetching and Displaying Rsvps","htmlContent":"<p>Now that we've got Rsvps saving and associated with their parent event, we can use some nice sequelize queries to get associated rsvps.</p><div class=\"action\">\n<p></p>\n\n<p>In the <code>events/show</code> route, update our query to <code>include</code> rsvps.</p>\n<pre><span class=\"c1\">// controllers/events.js</span>\n\n<span class=\"p\">...</span>\n\n<span class=\"c1\">// SHOW</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/events/:id'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">models</span><span class=\"p\">.</span><span class=\"nx\">Event</span><span class=\"p\">.</span><span class=\"nx\">findByPk</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">id</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">include</span><span class=\"o\">:</span> <span class=\"p\">[{</span> <span class=\"nx\">model</span><span class=\"o\">:</span> <span class=\"nx\">models</span><span class=\"p\">.</span><span class=\"nx\">Rsvp</span> <span class=\"p\">}]</span> <span class=\"p\">}).</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"nx\">event</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n        <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'events-show'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">event</span><span class=\"o\">:</span> <span class=\"nx\">event</span> <span class=\"p\">});</span>\n    <span class=\"p\">}).</span><span class=\"k\">catch</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n        <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">.</span><span class=\"nx\">message</span><span class=\"p\">);</span>\n    <span class=\"p\">})</span>\n<span class=\"p\">});</span>\n</pre>\n</div><p>Now in our template we can iterate over <code>event.Rsvps</code> to display them. We can also add a little counter of the number of rsvps above:</p><div class=\"action\">\n<p></p>\n\n<p>Update the <code>.col-lg-4 offset-lg-1</code> block in <code>views/events-show.handlebars</code> to the following:</p>\n<pre><span class=\"c\">&lt;!-- views/events-show.handlebars --&gt;</span>\n...\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"col-lg-4 offset-lg-1\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"d-flex justify-content-between\"</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">b</span><span class=\"p\">&gt;</span>RSVPs ({{event.Rsvps.length}})<span class=\"p\">&lt;/</span><span class=\"nt\">b</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/events/{{event.id}}/rsvps/new\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"btn btn-primary btn-sm\"</span><span class=\"p\">&gt;</span>RSVP<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n\n    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"list-group mt-4\"</span><span class=\"p\">&gt;</span>\n        {{#each event.Rsvps}}\n        <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"list-group-item\"</span><span class=\"p\">&gt;</span>\n            {{this.name}}\n        <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n        {{/each}}\n    <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n...\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODI4Ng==","title":"One More RSVP Button","htmlContent":"<p>We've got almost everything hooked up, but what about that RSVP button on the event cards on the home page? Let's get those wired up too!</p><div class=\"action\">\n<p></p>\n\n<p>Update the <code>&lt;a&gt;</code> for RSVPs in <code>views/events-index.handlebars</code> to the following:</p>\n<pre>...\n\n<span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/events/{{this.id}}/rsvps/new\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"btn btn-info\"</span><span class=\"p\">&gt;</span>Rsvp<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n\n...\n</pre>\n</div><p>Try out the button, and make sure everything is working!</p>"},{"id":"T0E6OlNlY3Rpb24tODI4Nw==","title":"Product So Far","htmlContent":"<p>Great work! You should now be able to see RSVPs for your event:</p><p><strong>RSVP Form</strong></p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P09-Adding-Rsvps/assets/rsvp-form.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P09-Adding-Rsvps/assets/rsvp-form.png\" alt=\"rsvp-form\" title=\"\">\n        </a></p><p><strong>Event Page With RSVPs</strong></p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P09-Adding-Rsvps/assets/rsvp-event.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P09-Adding-Rsvps/assets/rsvp-event.png\" alt=\"rsvp-event\" title=\"\">\n        </a></p>"},{"id":"T0E6OlNlY3Rpb24tODI4OA==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can see comments'</span>\n$ git push\n</pre>"},{"id":"T0E6OlNlY3Rpb24tODI4OQ==","title":"What Just Happened?","htmlContent":"<p>You created a relationship between two different tables in your database! Events each have a unique id. By saving the id of an Event with a Rsvp, we can find the Event that they are are associated with. Events can also find all of the Rsvps that are associated with their id.</p><p>This is a one to many relationship. This an important concept in database design, and an important tool you will use when managing data.</p>"}]},"next":{"id":"T0E6OlBhZ2UtMTUyOQ==","slug":"deleting-rsvps","title":"Deleting RSVPs"},"previous":{"id":"T0E6OlBhZ2UtMTUyOQ==","slug":"deleting-rsvps","title":"Deleting RSVPs"}},{"id":"T0E6OlBhZ2UtMTUyOQ==","title":"Deleting RSVPs","slug":"deleting-rsvps","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tODI5OA==","title":"Deleting RSVPs","htmlContent":"<ol>\n<li><del>Users can view all events (index)</del></li>\n<li><del>Users can create a event (new/create)</del></li>\n<li><del>Users can view one event (show)</del></li>\n<li><del>Users can edit a event (edit/update)</del></li>\n<li><del>Users can delete a event (destroy)</del></li>\n<li><del>Users can rsvp to events (/rsvps/create, /rsvps/new)</del></li>\n<li><strong>Users can cancel their rsvp (/rsvps/destroy)</strong></li>\n</ol><p>Finally, since we are creating rsvps, we should also be able to delete them.</p><p>Remember that currently we do not have authentication so we'll just be letting any user create and delete rsvps. If we developed this project for a real production use case, we would want to add authentication and only allow people to delete their own rsvps!</p>"},{"id":"T0E6OlNlY3Rpb24tODI5OQ==","title":"Deleting RSVPs","htmlContent":"<p>You need to define a route. Here is the list of the current routes with a new one added for the rsvp form at the bottom.</p><table>\n<thead>\n<tr>\n<th>URL</th>\n<th>HTTP Verb</th>\n<th>Action</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>/</td>\n<td>GET</td>\n<td>index</td>\n</tr>\n<tr>\n<td>/events/new</td>\n<td>GET</td>\n<td>new</td>\n</tr>\n<tr>\n<td>/events</td>\n<td>POST</td>\n<td>create</td>\n</tr>\n<tr>\n<td>/events/:id</td>\n<td>GET</td>\n<td>show</td>\n</tr>\n<tr>\n<td>/events/:id/edit</td>\n<td>GET</td>\n<td>edit</td>\n</tr>\n<tr>\n<td>/events/:id</td>\n<td>PUT/PATCH</td>\n<td>update</td>\n</tr>\n<tr>\n<td>/events/:id</td>\n<td>DELETE</td>\n<td>destroy</td>\n</tr>\n<tr>\n<td>/events/:eventId/rsvps/new</td>\n<td>GET</td>\n<td>new</td>\n</tr>\n<tr>\n<td>/events/:eventId/rsvps</td>\n<td>POST</td>\n<td>create</td>\n</tr>\n<tr>\n<td>/events/:eventId/rsvps/:id</td>\n<td>DELETE</td>\n<td>destroy</td>\n</tr>\n</tbody>\n</table><p>We'll use the <code>:id</code> url parameter to look up the rsvp we want to destroy.</p>"},{"id":"T0E6OlNlY3Rpb24tODMwMA==","title":"What the User Sees: Making a Delete Button","htmlContent":"<p>As always, we start with what the users sees and does. So let's make a link to delete a rsvp.</p><p>We can't set an <code>&lt;a&gt;</code> tag's method (it is always GET) so we are going to use a form to submit a DELETE request to our delete action path.</p><div class=\"action\">\n<p></p>\n\n<p>Add a button to each rsvp shown in an event by replacing the <code>.list-group mt-4</code> block in <code>views/events-show.handlebars</code> with the following:</p>\n<pre><span class=\"c\">&lt;!-- views/events-show.handlebars --&gt;</span>\n  ...\n    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"list-group mt-4\"</span><span class=\"p\">&gt;</span>\n      {{#each event.Rsvps}}\n        <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"list-group-item clearfix\"</span><span class=\"p\">&gt;</span>\n          <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"float-left\"</span><span class=\"p\">&gt;</span>\n            {{this.name}}\n          <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n          <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"float-right\"</span><span class=\"p\">&gt;</span>\n            <span class=\"p\">&lt;</span><span class=\"nt\">form</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"form-inline\"</span> <span class=\"na\">action</span><span class=\"o\">=</span><span class=\"s\">\"/events/{{../event.id}}/rsvps/{{this.id}}?_method=DELETE\"</span> <span class=\"na\">method</span><span class=\"o\">=</span><span class=\"s\">\"post\"</span><span class=\"p\">&gt;</span>\n              <span class=\"p\">&lt;</span><span class=\"nt\">button</span> <span class=\"na\">type</span><span class=\"o\">=</span><span class=\"s\">\"submit\"</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"btn btn-link btn-sm\"</span><span class=\"p\">&gt;</span>Remove<span class=\"p\">&lt;/</span><span class=\"nt\">button</span><span class=\"p\">&gt;</span>\n            <span class=\"p\">&lt;/</span><span class=\"nt\">form</span><span class=\"p\">&gt;</span>\n          <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n      {{/each}}\n    <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n  ...\n</pre>\n</div><p>If you try to submit this form, it won't work yet, because the route it points to does not exist. That is our next step.</p><div class=\"info\">\n<p></p>\n\n<p>Notice how we always move from what the user interacts with, to the controllers, and then finally to the models and database, and not the other way around. We do this intentionally because it is faster, and makes leaner more usable code and products.</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODMwMQ==","title":"Adding the Destroy Route","htmlContent":"<p>Now we need a destroy action route. After deleting the rsvp, it should redirect back to the parent event (<code>events-show</code>).</p><div class=\"action\">\n<p></p>\n\n<p>Add the following <code>/delete</code> route to <code>controllers/rsvps.js</code>:</p>\n<pre><span class=\"c1\">// controllers/rsvps.js</span>\n<span class=\"p\">...</span>\n  <span class=\"c1\">// DELETE</span>\n  <span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"k\">delete</span><span class=\"p\">(</span><span class=\"s1\">'/events/:eventId/rsvps/:id'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"nx\">models</span><span class=\"p\">.</span><span class=\"nx\">Rsvp</span><span class=\"p\">.</span><span class=\"nx\">findByPk</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">id</span><span class=\"p\">).</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"nx\">rsvp</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n          <span class=\"nx\">rsvp</span><span class=\"p\">.</span><span class=\"nx\">destroy</span><span class=\"p\">();</span>\n          <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">redirect</span><span class=\"p\">(</span><span class=\"sb\">`/events/</span><span class=\"si\">${</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">eventId</span><span class=\"si\">}</span><span class=\"sb\">`</span><span class=\"p\">);</span>\n      <span class=\"p\">}).</span><span class=\"k\">catch</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n          <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">);</span>\n      <span class=\"p\">});</span>\n  <span class=\"p\">});</span>\n</pre>\n</div><p>Now try deleting a rsvp.</p>"},{"id":"T0E6OlNlY3Rpb24tODMwMg==","title":"Git Commit and Push, and Push to Heroku","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can delete rsvps'</span>\n$ git push\n$ git push heroku master\n</pre><p>Before you can test your project on Heroku, remember we made some changes to our DB, and we need to run the migrations on Heroku:</p><div class=\"action\">\n<p></p>\n\n<p>Run the migrations on Heroku</p>\n<pre>$ heroku run bash\n$ sequelize -m <span class=\"c1\"># this just makes sure sequelize is installed</span>\n$ sequelize db:migrate\n</pre>\n</div><p>Open up your Heroku project and do some manual testing. Great work!</p>"},{"id":"T0E6OlNlY3Rpb24tODMwMw==","title":"What Happened","htmlContent":"<p>So now we've completed all our user stories</p><ol>\n<li>Users can view all events (index)</li>\n<li>Users can create a event (new/create)</li>\n<li>Users can view one event (show)</li>\n<li>Users can delete a event (destroy)</li>\n<li>Users can edit a event (edit/update)</li>\n<li>Users can rsvp on events (rsvps/create)</li>\n<li>Users can delete rsvps (rsvps/destroy)</li>\n</ol><p>You used <strong>Resource Based Development</strong> and <strong>Resourceful Routing</strong> to build a event based app! Now let's put some final touches on it to really tie it all together.</p>"}]},"next":{"id":"T0E6OlBhZ2UtMTUzMA==","slug":"bells-and-whistles-2ug=","title":"Bells and Whistles"},"previous":{"id":"T0E6OlBhZ2UtMTUzMA==","slug":"bells-and-whistles-2ug=","title":"Bells and Whistles"}},{"id":"T0E6OlBhZ2UtMTUzMA==","title":"Bells and Whistles","slug":"bells-and-whistles-2ug=","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tODMwNA==","title":"Bells and Whistles","htmlContent":"<p>Now there are a few more things we can do to tighten up our website and make it look more like the big leagues. Let's look at a few.</p>"},{"id":"T0E6OlNlY3Rpb24tODMwNQ==","title":"Displaying \"Created At\" Time","htmlContent":"<p>Let's display a timestamp of when the event was created. Normally this would require some middleware to accomplish our needs, but if you look at the <code>migration</code> files, you'll see that all of our models come with a <code>createdAt</code> definition by default! Now we just need to display them.</p><div class=\"action\">\n<p></p>\n\n<p>Update <code>views/events-show.handlebars</code> to include the <code>createdAt</code> property:</p>\n<pre><span class=\"c\">&lt;!-- views/events-show.handlebars --&gt;</span>\n\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"row mt-4\"</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"col-lg-6\"</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">img</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"img-fluid w-100 rounded mb-3\"</span> <span class=\"na\">src</span><span class=\"o\">=</span><span class=\"s\">\"{{event.imgUrl}}\"</span> <span class=\"na\">alt</span><span class=\"o\">=</span><span class=\"s\">\"Card image cap\"</span><span class=\"p\">&gt;</span>\n<strong>        <span class=\"p\">&lt;</span><span class=\"nt\">small</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"text-muted\"</span><span class=\"p\">&gt;</span>Created on: {{event.createdAt}}<span class=\"p\">&lt;/</span><span class=\"nt\">small</span><span class=\"p\">&gt;</span>\n</strong>\n        <span class=\"p\">&lt;</span><span class=\"nt\">h3</span><span class=\"p\">&gt;</span>{{event.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">h3</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"lead\"</span><span class=\"p\">&gt;</span>{{event.desc}}<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"text-right\"</span><span class=\"p\">&gt;</span>\n            <span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"/events/{{event.id}}/edit\"</span><span class=\"p\">&gt;</span>Edit<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n        <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n\n...\n\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span></pre>\n</div><p>Refresh your browser and navigate to an event page. Seems a bit long for a date and time, doesn't it? What you see there is called a Unix timestamp.</p><pre><span class=\"nx\">Mon</span> <span class=\"nx\">Nov</span> <span class=\"mi\">26</span> <span class=\"mi\">2018</span> <span class=\"mi\">12</span><span class=\"o\">:</span><span class=\"mi\">57</span><span class=\"o\">:</span><span class=\"mi\">54</span> <span class=\"nx\">GMT</span><span class=\"o\">-</span><span class=\"mi\">0800</span> <span class=\"p\">(</span><span class=\"nx\">Pacific</span> <span class=\"nx\">Standard</span> <span class=\"nx\">Time</span><span class=\"p\">)</span>\n</pre><p>It technically says the date and time when the review was created, but it isn't very readable for humans! We could parse it manually, but let's use a neat and very common js library called <a href=\"https://momentjs.com/\" target=\"_blank\">moment</a> to parse that time into something more readable.</p><div class=\"action\">\n<p>\nInstall moment\n<code>bash\n$ npm install moment --save\n</code></p>\n\n<p>Now update the <code>/show</code> route in <code>controllers/events.js</code> to format the <code>createdAt</code> date into something we can read:</p>\n<pre><span class=\"p\">...</span>\n\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/events/:id'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">models</span><span class=\"p\">.</span><span class=\"nx\">Event</span><span class=\"p\">.</span><span class=\"nx\">findByPk</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">id</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">include</span><span class=\"o\">:</span> <span class=\"p\">[{</span> <span class=\"nx\">model</span><span class=\"o\">:</span> <span class=\"nx\">models</span><span class=\"p\">.</span><span class=\"nx\">Rsvp</span> <span class=\"p\">}]</span> <span class=\"p\">}).</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"nx\">event</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n        <span class=\"kd\">let</span> <span class=\"nx\">createdAt</span> <span class=\"o\">=</span> <span class=\"nx\">event</span><span class=\"p\">.</span><span class=\"nx\">createdAt</span><span class=\"p\">;</span>\n        <span class=\"nx\">createdAt</span> <span class=\"o\">=</span> <span class=\"nx\">moment</span><span class=\"p\">(</span><span class=\"nx\">createdAt</span><span class=\"p\">).</span><span class=\"nx\">format</span><span class=\"p\">(</span><span class=\"s1\">'MMMM Do YYYY, h:mm:ss a'</span><span class=\"p\">);</span>\n        <span class=\"nx\">event</span><span class=\"p\">.</span><span class=\"nx\">createdAtFormatted</span> <span class=\"o\">=</span> <span class=\"nx\">createdAt</span><span class=\"p\">;</span>\n        <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'events-show'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">event</span><span class=\"o\">:</span> <span class=\"nx\">event</span> <span class=\"p\">});</span>\n    <span class=\"p\">}).</span><span class=\"k\">catch</span><span class=\"p\">((</span><span class=\"nx\">err</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n        <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"nx\">err</span><span class=\"p\">.</span><span class=\"nx\">message</span><span class=\"p\">);</span>\n    <span class=\"p\">})</span>\n<span class=\"p\">});</span>\n\n<span class=\"p\">...</span>\n</pre>\n</div><p>Finally, let's use our new property:</p><div class=\"action\">\n<p></p>\n\n<p>Update <code>views/events-show.handlebars</code> to include the <code>createdAtFormatted</code> property:</p>\n<pre><span class=\"c\">&lt;!-- views/events-show.handlebars --&gt;</span>\n...\n\n<span class=\"p\">&lt;</span><span class=\"nt\">small</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"text-muted\"</span><span class=\"p\">&gt;</span>Created on: {{event.createdAtFormatted}}<span class=\"p\">&lt;/</span><span class=\"nt\">small</span><span class=\"p\">&gt;</span>\n\n...\n</pre>\n</div><p>Reload your browser and check the timestamp. Doesn't that look so much better?</p><div class=\"info\">\n<p>\nWant it to display differently? Use the <a href=\"https://momentjs.com/\" target=\"_blank\">moment documentation</a> to tweak the <strong>format string</strong> until you are happy with how the text displays.</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODMwNg==","title":"Adding a Footer","htmlContent":"<p>Now let's add a footer (Brought to you by mdbootstrap.com).</p><div class=\"action\">\n<p></p>\n\n<p>Add the following code after the <code>{{{body}}}</code> tag, but before the <code>&lt;/body&gt;</code> tag or any <code>&lt;script&gt;</code> tags in <code>views/layouts/main.handlebars</code>.</p>\n<pre><span class=\"c\">&lt;!-- main.handlebars --&gt;</span>\n...\n\n<span class=\"c\">&lt;!-- Footer --&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">footer</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"page-footer font-small blue pt-4\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"container-fluid text-center\"</span><span class=\"p\">&gt;</span>\n     <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"row\"</span><span class=\"p\">&gt;</span>\n     <span class=\"p\">&lt;</span><span class=\"nt\">hr</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"clearfix w-100 d-md-none pb-3\"</span><span class=\"p\">&gt;</span>\n     <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"col-md-6 mb-md-0 mb-3\"</span><span class=\"p\">&gt;</span>\n         <span class=\"p\">&lt;</span><span class=\"nt\">h5</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"text-uppercase\"</span><span class=\"p\">&gt;</span>Links<span class=\"p\">&lt;/</span><span class=\"nt\">h5</span><span class=\"p\">&gt;</span>\n         <span class=\"p\">&lt;</span><span class=\"nt\">ul</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"list-unstyled\"</span><span class=\"p\">&gt;</span>\n             <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"#!\"</span><span class=\"p\">&gt;</span>Link 1<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n             <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"#!\"</span><span class=\"p\">&gt;</span>Link 2<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n             <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"#!\"</span><span class=\"p\">&gt;</span>Link 3<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n             <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"#!\"</span><span class=\"p\">&gt;</span>Link 4<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n         <span class=\"p\">&lt;/</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n     <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n     <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"col-md-6 mb-md-0 mb-3\"</span><span class=\"p\">&gt;</span>\n         <span class=\"p\">&lt;</span><span class=\"nt\">h5</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"text-uppercase\"</span><span class=\"p\">&gt;</span>Links<span class=\"p\">&lt;/</span><span class=\"nt\">h5</span><span class=\"p\">&gt;</span>\n         <span class=\"p\">&lt;</span><span class=\"nt\">ul</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"list-unstyled\"</span><span class=\"p\">&gt;</span>\n             <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"#!\"</span><span class=\"p\">&gt;</span>Link 1<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n             <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"#!\"</span><span class=\"p\">&gt;</span>Link 2<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n             <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"#!\"</span><span class=\"p\">&gt;</span>Link 3<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n             <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"#!\"</span><span class=\"p\">&gt;</span>Link 4<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n         <span class=\"p\">&lt;/</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n     <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n     <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"footer-copyright text-center py-3\"</span><span class=\"p\">&gt;</span>&copy; 2018 Copyright:\n     <span class=\"p\">&lt;</span><span class=\"nt\">a</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"https://mdbootstrap.com/education/bootstrap/\"</span><span class=\"p\">&gt;</span> MDBootstrap.com<span class=\"p\">&lt;/</span><span class=\"nt\">a</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">footer</span><span class=\"p\">&gt;</span>\n\n...\n</pre>\n</div><p>Beautiful! Make any visual changes you like.</p>"},{"id":"T0E6OlNlY3Rpb24tODMwNw==","title":"Adding a Bootstrap Theme","htmlContent":"<p>Now if we want to customize our style a little bit, we can add a free bootstrap theme. One popular website for finding these is called <a href=\"https://bootswatch.com/\" target=\"_blank\">Bootswatch</a>.</p><p>You can pick whichever you like, but for these instructions we'll use the \"flatly\" theme.</p><div class=\"action\">\n<p>\nGo to <a href=\"https://bootswatch.com/\" target=\"_blank\">Bootswatch</a> and select a theme from the <code>Themes</code> dropdown</p>\n\n<p>Select the dropdown of the name of the style you selected. For example, if you like the <code>Flatly</code> style, you should see a <code>Flatly</code> dropdown as the last nav bar item on the left</p>\n\n<p>Select the <code>bootstrap.min.css</code> option in the dropdown\nCopy the URL into the <code>&lt;head&gt;</code> tag in <code>views/layouts/main.handlebars</code> to include the style you want. Make sure that this theme comes AFTER your link to bootstrap itself. Otherwise it won't work.</p>\n<pre><span class=\"p\">&lt;</span><span class=\"nt\">head</span><span class=\"p\">&gt;</span>\n  ...\n\n  <span class=\"p\">&lt;</span><span class=\"nt\">link</span> <span class=\"na\">rel</span><span class=\"o\">=</span><span class=\"s\">\"stylesheet\"</span> <span class=\"na\">href</span><span class=\"o\">=</span><span class=\"s\">\"https://bootswatch.com/4/flatly/bootstrap.min.css\"</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">head</span><span class=\"p\">&gt;</span>\n</pre>\n</div><p>Now you can mess around with the CSS classes you have previously applied to achieve the look that you want!.</p>"},{"id":"T0E6OlNlY3Rpb24tODMwOA==","title":"Product So Far","htmlContent":"<p>Yours may look different depending on the styles/formatting you chose, but it should look similar to this now:</p><p><strong>Home Page</strong></p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P11-Bells-And-Whistles/assets/styled-home.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P11-Bells-And-Whistles/assets/styled-home.png\" alt=\"styled-home\" title=\"\">\n        </a></p><p><strong>Event Page</strong></p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P11-Bells-And-Whistles/assets/styled-event.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P11-Bells-And-Whistles/assets/styled-event.png\" alt=\"styled-event\" title=\"\">\n        </a></p>"},{"id":"T0E6OlNlY3Rpb24tODMwOQ==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'added createdAt, footer, and bootstrap theme'</span>\n$ git push\n$ git push heroku master\n</pre><p>Congrats! Not too shabby for one of your first web apps! We encourage you to check out the stretch challenges in the last chapter to build this out even further!</p>"},{"id":"T0E6OlNlY3Rpb24tODMxMA==","title":"Feedback and Review - 2 minutes","htmlContent":"<p><strong>We promise this won't take longer than 2 minutes!</strong></p><p>Please take a moment to rate your understanding of learning outcomes from this tutorial, and how we can improve it via our <a href=\"https://forms.gle/gnEK8jAjRHb5cD5e6\" target=\"_blank\">tutorial feedback form</a></p><p>This allows us to get feedback on how well the students are grasping the learning outcomes, and tells us where we can improve the tutorial experience.</p>"}]},"next":{"id":"T0E6OlBhZ2UtMTUzMQ==","slug":"extra-challenges","title":"Extra Challenges"},"previous":{"id":"T0E6OlBhZ2UtMTUzMQ==","slug":"extra-challenges","title":"Extra Challenges"}},{"id":"T0E6OlBhZ2UtMTUzMQ==","title":"Extra Challenges","slug":"extra-challenges","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tNjMwNA==","title":"Extra Challenges","htmlContent":"<p>This last chapter is all stretch challenges for those who want to dive deeper into the following areas:</p><ul>\n<li>Refactoring the code to be more efficient</li>\n<li>Adding additional functionality (such as comments)</li>\n</ul><p>If any of those sound interesting to you, check them out! We highly encourage it!</p>"},{"id":"T0E6OlNlY3Rpb24tNjMwNQ==","title":"Async / Await","htmlContent":"<p>JavaScript ES7 (2016), a newer version than ES6 (2015), has a really neat feature that you can add to your project called <code>async</code>/<code>await</code>.</p><p>In some places in our code we have what is called <a href=\"http://callbackhell.com/\" target=\"_blank\">Callback Hell</a>. We can fix this once an for all with <code>async</code>/<code>await</code>.</p><p>Check out this example, which covers the <code>/show</code> route for a <em>very similar</em> event website to the one you just built.</p><p>This implementation:</p><pre><span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/events/:id'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">models</span><span class=\"p\">.</span><span class=\"nx\">Event</span><span class=\"p\">.</span><span class=\"nx\">findById</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">id</span><span class=\"p\">).</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"nx\">event</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">event</span><span class=\"p\">.</span><span class=\"nx\">getComments</span><span class=\"p\">({</span> <span class=\"nx\">order</span><span class=\"o\">:</span> <span class=\"p\">[</span> <span class=\"p\">[</span><span class=\"s1\">'createdAt'</span><span class=\"p\">,</span> <span class=\"s1\">'DESC'</span><span class=\"p\">]</span> <span class=\"p\">]</span> <span class=\"p\">}).</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"nx\">comments</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n      <span class=\"nx\">event</span><span class=\"p\">.</span><span class=\"nx\">getRsvps</span><span class=\"p\">({</span> <span class=\"nx\">order</span><span class=\"o\">:</span> <span class=\"p\">[</span> <span class=\"p\">[</span><span class=\"s1\">'createdAt'</span><span class=\"p\">,</span> <span class=\"s1\">'DESC'</span><span class=\"p\">]</span> <span class=\"p\">]</span> <span class=\"p\">}).</span><span class=\"nx\">then</span><span class=\"p\">(</span><span class=\"nx\">rsvps</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n        <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'events-show'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">comments</span><span class=\"o\">:</span> <span class=\"nx\">comments</span><span class=\"p\">,</span> <span class=\"nx\">event</span><span class=\"o\">:</span> <span class=\"nx\">event</span><span class=\"p\">,</span> <span class=\"nx\">rsvps</span><span class=\"o\">:</span> <span class=\"nx\">rsvps</span> <span class=\"p\">});</span>\n      <span class=\"p\">});</span>\n    <span class=\"p\">});</span>\n  <span class=\"p\">});</span>\n<span class=\"p\">});</span>\n</pre><p>is the same as:</p><pre><span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/events/:id'</span><span class=\"p\">,</span> <span class=\"nx\">async</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"kd\">let</span> <span class=\"nx\">event</span> <span class=\"o\">=</span> <span class=\"nx\">await</span> <span class=\"nx\">models</span><span class=\"p\">.</span><span class=\"nx\">Event</span><span class=\"p\">.</span><span class=\"nx\">findById</span><span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">.</span><span class=\"nx\">params</span><span class=\"p\">.</span><span class=\"nx\">id</span><span class=\"p\">)</span>\n  <span class=\"kd\">let</span> <span class=\"nx\">comments</span> <span class=\"o\">=</span> <span class=\"nx\">event</span><span class=\"p\">.</span><span class=\"nx\">getComments</span><span class=\"p\">({</span> <span class=\"nx\">order</span><span class=\"o\">:</span> <span class=\"p\">[</span> <span class=\"p\">[</span><span class=\"s1\">'createdAt'</span><span class=\"p\">,</span> <span class=\"s1\">'DESC'</span><span class=\"p\">]</span> <span class=\"p\">]</span> <span class=\"p\">});</span>\n  <span class=\"kd\">let</span> <span class=\"nx\">rsvps</span> <span class=\"o\">=</span> <span class=\"nx\">event</span><span class=\"p\">.</span><span class=\"nx\">getRsvps</span><span class=\"p\">()</span>\n  <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'events-show'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">comments</span><span class=\"o\">:</span> <span class=\"nx\">comments</span><span class=\"p\">,</span> <span class=\"nx\">event</span><span class=\"o\">:</span> <span class=\"nx\">event</span><span class=\"p\">,</span> <span class=\"nx\">rsvps</span><span class=\"o\">:</span> <span class=\"nx\">rsvps</span> <span class=\"p\">});</span>\n<span class=\"p\">});</span>\n</pre><p>Notice that the whole function is called <code>async</code>, and the <code>await</code> keyword prefaces any function that returns a promise.</p><div class=\"challenge\">\n<p></p>\n\n<p>Try using this pattern to update one of your own routes.</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tNjMwNg==","title":"Adding Comments","htmlContent":"<p>Imagine you get some feedback that people planning and rsvp'd to events would like to comment on the event like a \"wall\" on facebook.</p><p>Comments are a lot like Rsvps, so you should be able to add them by referencing that code.</p><div class=\"challenge\">\n<p></p>\n\n<p>Here are the steps you should take:</p>\n\n<ol>\n<li>Add a new comment form to the <code>events-show</code> template below the <code>{{event.desc}}</code>.</li>\n<li>Have that form submit to a <strong>nested</strong> comments create action in its own <code>comments.js</code> controller.</li>\n<li>Create a comment model with the attribute <code>content</code>, and then add the <strong>foreign key</strong> <code>EventId</code> just like Rsvps has. (Reminder - make sure to add the association to the Comment and Event models)</li>\n<li>See if you can create a comment associated with its parent event.</li>\n<li>Now get your comments from the event. (Hint - You can use the command <code>include: { all: true}</code> to get all models associated with your event, and then access its comments via <code>event.Comments</code> like <code>event.Rsvps</code>.)</li>\n<li>Display your comments below by iterating through <code>event.Comments</code>.</li>\n</ol>\n</div>"}]},"next":null,"previous":null}]}},"page":{"id":"T0E6OlBhZ2UtMTUyMA==","title":"See All Events","slug":"index-events","sections":{"nodes":[{"id":"T0E6OlNlY3Rpb24tODI0NQ==","title":"See All Events","htmlContent":"<p>Following our <strong>User Stories</strong> we are going to define a single <strong>Resource</strong> in this app called an <code>Event</code>.</p><ol>\n<li><strong>Users can view all events (index)</strong></li>\n<li>Users can create a event (new/create)</li>\n<li>Users can view one event (show)</li>\n<li>Users can edit a event (edit/update)</li>\n<li>Users can delete a event (destroy)</li>\n<li>Users can rsvp to events (/rsvps/create, /rsvps/new)</li>\n<li>Users can cancel their rsvp (/rsvps/destroy)</li>\n</ol><p>A <strong>Resource</strong> is an abstract object that we use to organize data, code, and the features of our app. For example, in a <code>User</code> resource we can keep track of logging in and out, email and passwords, and people's birthdays. In a blog, we might have an <code>Article</code> or <code>Post</code> resource where we would track the titles and bodies of articles and keep track of the code for publishing and sharing them.</p><p>Resources can also be related to each other. For example, articles may have comments; a building resource might have floors, and the floors may have units; a user might have friends (like in Facebook).</p><p>All resources have a few actions in common that are called <strong>Resourceful Routes</strong>. Memorize this table of routes:</p><table>\n<thead>\n<tr>\n<th>URL</th>\n<th>HTTP Verb</th>\n<th>Action</th>\n<th>What it Does</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>/events</td>\n<td>GET</td>\n<td>index</td>\n<td>See all events</td>\n</tr>\n<tr>\n<td>/events/new</td>\n<td>GET</td>\n<td>new</td>\n<td>See new event form</td>\n</tr>\n<tr>\n<td>/events</td>\n<td>POST</td>\n<td>create</td>\n<td>Create a new event</td>\n</tr>\n<tr>\n<td>/events/:id</td>\n<td>GET</td>\n<td>show</td>\n<td>See one event</td>\n</tr>\n<tr>\n<td>/events/:id/edit</td>\n<td>GET</td>\n<td>edit</td>\n<td>See an edit event form</td>\n</tr>\n<tr>\n<td>/events/:id</td>\n<td>PATCH/PUT</td>\n<td>update</td>\n<td>Update a event</td>\n</tr>\n<tr>\n<td>/events/:id</td>\n<td>DELETE</td>\n<td>destroy</td>\n<td>Delete a event</td>\n</tr>\n</tbody>\n</table><p>We're going to start with the <code>index</code> action and then <code>show</code>, and then we'll look at the <code>create</code>, <code>edit</code>, <code>update</code>, and <code>delete</code>.</p>"},{"id":"T0E6OlNlY3Rpb24tODI0Ng==","title":"Adding an '/events' Route","htmlContent":"<p>Let's make a route to <code>/events</code> for the index action where we can see all the events that we've created. Eventually this will be on our root route, but we can start making it its own separate path.</p><div class=\"action\">\n<p></p>\n\n<p>Add the following below the <code>app.get('/'...)</code> call in <code>app.js</code>:</p>\n<pre><span class=\"c1\">// OUR MOCK ARRAY OF PROJECTS</span>\n<span class=\"kd\">var</span> <span class=\"nx\">events</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n  <span class=\"p\">{</span> <span class=\"nx\">title</span><span class=\"o\">:</span> <span class=\"s2\">\"I am your first event\"</span><span class=\"p\">,</span> <span class=\"nx\">desc</span><span class=\"o\">:</span> <span class=\"s2\">\"A great event that is super fun to look at and good\"</span><span class=\"p\">,</span> <span class=\"nx\">imgUrl</span><span class=\"o\">:</span> <span class=\"s2\">\"https://img.purch.com/w/660/aHR0cDovL3d3dy5saXZlc2NpZW5jZS5jb20vaW1hZ2VzL2kvMDAwLzA4OC85MTEvb3JpZ2luYWwvZ29sZGVuLXJldHJpZXZlci1wdXBweS5qcGVn\"</span> <span class=\"p\">},</span>\n  <span class=\"p\">{</span> <span class=\"nx\">title</span><span class=\"o\">:</span> <span class=\"s2\">\"I am your second event\"</span><span class=\"p\">,</span> <span class=\"nx\">desc</span><span class=\"o\">:</span> <span class=\"s2\">\"A great event that is super fun to look at and good\"</span><span class=\"p\">,</span> <span class=\"nx\">imgUrl</span><span class=\"o\">:</span> <span class=\"s2\">\"https://img.purch.com/w/660/aHR0cDovL3d3dy5saXZlc2NpZW5jZS5jb20vaW1hZ2VzL2kvMDAwLzA4OC85MTEvb3JpZ2luYWwvZ29sZGVuLXJldHJpZXZlci1wdXBweS5qcGVn\"</span> <span class=\"p\">},</span>\n  <span class=\"p\">{</span> <span class=\"nx\">title</span><span class=\"o\">:</span> <span class=\"s2\">\"I am your third event\"</span><span class=\"p\">,</span> <span class=\"nx\">desc</span><span class=\"o\">:</span> <span class=\"s2\">\"A great event that is super fun to look at and good\"</span><span class=\"p\">,</span> <span class=\"nx\">imgUrl</span><span class=\"o\">:</span> <span class=\"s2\">\"https://img.purch.com/w/660/aHR0cDovL3d3dy5saXZlc2NpZW5jZS5jb20vaW1hZ2VzL2kvMDAwLzA4OC85MTEvb3JpZ2luYWwvZ29sZGVuLXJldHJpZXZlci1wdXBweS5qcGVn\"</span> <span class=\"p\">}</span>\n<span class=\"p\">]</span>\n\n<span class=\"c1\">// INDEX</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/events'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'events-index'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">events</span><span class=\"o\">:</span> <span class=\"nx\">events</span> <span class=\"p\">});</span>\n<span class=\"p\">})</span>\n</pre>\n</div><p>Notice how we are making a mock array of events, and sending that in as an object into the template <code>{ events: events }</code>. So the variable <code>events</code> will be available in our template!</p>"},{"id":"T0E6OlNlY3Rpb24tODI0Nw==","title":"Errors are Your Friends!","htmlContent":"<div class=\"action\">\n<p></p>\n\n<p>Send your browser to your <code>/events</code> path by going to <code>http://localhost:3000/events</code>. What do you see?</p>\n</div><p>An error!</p><p><strong>That's ok! Errors are our friends</strong>.</p><p>What does the error say? I bet it says something like \"I can't find the template 'events-index'\". That makes sense because we haven't made it yet! It's ok to complete coding tasks that throw a predictable error, and then use that error like a sign post.</p><div class=\"info\">\n<p>\nErrors often tell you the next step you need to take. In this case the error is telling you that the template does not exist. Let's make it!</p>\n</div><p>So to fix this error, let's add the template <code>views/events-index.handlebars</code>. We're going to use the Handlebars.js <code>{{#each}}</code> iterator to loop over our array of events and display each one's title.</p><div class=\"action\">\n<p></p>\n\n<p>Add <code>views/events-index.handlebars</code> to your project, and then put the following code into it:</p>\n<pre><span class=\"c\">&lt;!-- events-index --&gt;</span>\n<span class=\"p\">&lt;</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>Events<span class=\"p\">&lt;/</span><span class=\"nt\">h1</span><span class=\"p\">&gt;</span>\n{{#each events}}\n  <span class=\"p\">&lt;</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>{{this.title}}<span class=\"p\">&lt;/</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">img</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">\"img-fluid\"</span> <span class=\"na\">src</span><span class=\"o\">=</span><span class=\"s\">\"{{this.imgUrl}}\"</span> <span class=\"na\">alt</span><span class=\"o\">=</span><span class=\"s\">\"Card image cap\"</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>{{this.description}}<span class=\"p\">&lt;/</span><span class=\"nt\">p</span><span class=\"p\">&gt;</span>\n{{/each}}\n</pre>\n</div><p>If you refresh <code>localhost:3000/events</code> now what do you see?</p><div class=\"solution\">\n<p>\nYou should see the mock events we wrote into code. Can you add to them or change them?</p>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODI0OA==","title":"Setting the Root Route - '/'","htmlContent":"<p>Let's update the <code>/events</code> route to be our root route. Just change the path from <code>/events</code> to <code>/</code> and delete or comment out the hello world root route we made before.</p><div class=\"action\">\n<p></p>\n\n<p>Update the call to <code>app.get('/')</code> to render <code>events-index</code> in <code>app.js</code>:</p>\n<pre><span class=\"c1\">// INDEX</span>\n<span class=\"nx\">app</span><span class=\"p\">.</span><span class=\"nx\">get</span><span class=\"p\">(</span><span class=\"s1\">'/'</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">req</span><span class=\"p\">,</span> <span class=\"nx\">res</span><span class=\"p\">)</span> <span class=\"p\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"nx\">res</span><span class=\"p\">.</span><span class=\"nx\">render</span><span class=\"p\">(</span><span class=\"s1\">'events-index'</span><span class=\"p\">,</span> <span class=\"p\">{</span> <span class=\"nx\">events</span><span class=\"o\">:</span> <span class=\"nx\">events</span> <span class=\"p\">});</span>\n<span class=\"p\">})</span>\n</pre>\n</div>"},{"id":"T0E6OlNlY3Rpb24tODI0OQ==","title":"Product So Far","htmlContent":"<p>Now navigate to <code>localhost:3000</code>, and make sure you see those puppies!</p><p><a href=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P01-Index-Events/assets/puppies.png\" target=\"_blank\">\n          <img src=\"https://cdn.jsdelivr.net/gh/MakeSchool-Tutorials/Make-Parties@59b30afc31a2388069df0dd61fcba41e95fd2d22/P01-Index-Events/assets/puppies.png\" alt=\"puppies\" title=\"\">\n        </a></p>"},{"id":"T0E6OlNlY3Rpb24tODI1MA==","title":"Now Commit","htmlContent":"<pre>$ git add .\n$ git commit -m <span class=\"s1\">'Users can see all mock events'</span>\n$ git push\n</pre>"},{"id":"T0E6OlNlY3Rpb24tODI1MQ==","title":"Stretch Challenge","htmlContent":"<p>Still hankering for more? Use these <strong>Stretch Challenge</strong> sections to implement additional functionality to your project. Note that you will never <em>need</em> to implement these in order to finish the tutorial, but if you want extra practice, or want to try out some advanced functionality, then this is for you!</p><div class=\"challenge\">\n<p></p>\n\n<p>Can you make changes to your <code>events</code> array in <code>app.js</code> and see it reflected in your <code>events-index</code> template?</p>\n</div>"}]},"next":{"id":"T0E6OlBhZ2UtMTUyMQ==","slug":"adding-bootstrap-iFg=","title":"Styling with Bootstrap"},"previous":{"id":"T0E6OlBhZ2UtMTUyMQ==","slug":"adding-bootstrap-iFg=","title":"Styling with Bootstrap"}}}},"staticQueryHashes":[]}