Skip to content

Instantly share code, notes, and snippets.

@jmt75200
Forked from theRemix/MEH to MVC.md
Last active August 29, 2015 14:16
Show Gist options
  • Save jmt75200/98805fd3b8c7ee5a73f2 to your computer and use it in GitHub Desktop.
Save jmt75200/98805fd3b8c7ee5a73f2 to your computer and use it in GitHub Desktop.

MEH to MVC

Diagrams

mvc

mvc

The Controller

splitting up your app.js

setup your routes

using Router()

The MEH app will have it's routes refactored into external modules
Consider the resource named 'gallery' as an example

method path action response
GET / list gets all Photo documents from db then renders a jade template listing all photos
GET /gallery/:id show gets a single Photo from db then renders a jade template with photo details
GET /new_photo new_photo renders a jade template containing a form
POST /gallery create_photo saves new Photo to db then redirects to admin
GET /gallery/:id/edit edit_photo gets a single Photo from db then renders a jade template containing a form pre-filled with photo values
PUT /gallery/:id update_photo saves existing Photo to db then redirects to admin
DELETE /gallery/:id delete_photo deletes Photo from db then redirects to admin
GET /admin admin gets all [resources] then renders a jade template that lists all items with edit and delete buttons

This routing table will not change.

Create a module in your server directory (where your server-side app.js is)
in a new subdirectory controllers named gallery.js

server/
  app.js
  controllers/
    gallery.js
  ...

Follow this guide to use Router() to move all your existing routes from app.js into mountable routes in gallery.js
http://expressjs.com/guide/routing.html

At the top of gallery.js, require express and express.Router()

var express = require('express');
var router = express.Router();

the app.get('/', function(req, res){...}) route will change in a different way than the others, since it is accessed by the root url '/'
change it to router.list = function(req, res){...} we will access this directly later, in app.js


all the other routes will use router.*()

app.get('/gallery/:id', function (req, res) {..})
becomes
router.get('/:id', function (req, res) {..})
we removed /gallery since all of these routes will be mounted as in the /gallery path


app.get('/new_photo', function (req, res) {..})
becomes
router.get('/new', function (req, res) {..}) this route now conflicts with '/:id', so this should be moved above it, before the '/:id' route


app.post('/gallery', function (req, res) {..})
becomes
router.post('/', function (req, res) {..})


app.get('/gallery/:id/edit', function (req, res) {..})
becomes
router.get('/:id/edit', function (req, res) {..})


app.put('/gallery/:id', function (req, res) {..})
becomes
router.put('/:id', function (req, res) {..})


app.delete('/gallery/:id', function (req, res) {..})
becomes
router.delete('/:id', function (req, res) {..})


expose this router module to the rest of the application
module.exports = router;

Mount the new module in app.js

Near the top of app.js, require the gallery module
var gallery = require('./controllers/gallery');

After your middleware, (where your routes, used to be) load the router module
app.use('/gallery', gallery);

Handle the root route '/'

// Renders Main Gallery Page
app.get('/', gallery.list);

New routing table

method path action response
GET / list gets all Photo documents from db then renders a jade template listing all photos
GET /gallery/new new_photo renders a jade template containing a form
GET /gallery/:id show gets a single Photo from db then renders a jade template with photo details
POST /gallery create_photo saves new Photo to db then redirects to admin
GET /gallery/:id/edit edit_photo gets a single Photo from db then renders a jade template containing a form pre-filled with photo values
PUT /gallery/:id update_photo saves existing Photo to db then redirects to admin
DELETE /gallery/:id delete_photo deletes Photo from db then redirects to admin
GET /admin admin gets all [resources] then renders a jade template that lists all items with edit and delete buttons

note the order of new_photo and show have switched, and the path to new_photo has changed

The Model

Create a models subdirectory in the same directory that app.js is in.
Create a photo.js file in that subdirectory.

server/
  app.js
  controllers/
    gallery.js
  models/
    photo.js
  ...

In app.js, move the Schema definition, and Model definition, to photo.js.
leave your mongoose.connect(...) line in app.js

In photo.js, require the mongoose module (again) at the top.

photo.js should define the photoSchema

Instead of creating a Photo model and assigning it to a Photo variable, export the model so that it's accessible from the other parts of the app.
var Photo = mongoose.model('Photo', photoSchema);
becomes
module.exports = mongoose.model('Photo', photoSchema);

In gallery.js, require the photo model as Photo
var Photo = require('../models/photo');


a little more info on mvc

https://developer.chrome.com/apps/app_frameworks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment