Last active
May 21, 2016 21:28
-
-
Save sailsinaction/f5694bfed9a552d56c5e7492dcc871ad to your computer and use it in GitHub Desktop.
Chapter 12 - Gists
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.d8888b. 888 888 d888 .d8888b. .d8888b. d8b 888 | |
d88P Y88b 888 888 d8888 d88P Y88b d88P Y88b Y8P 888 | |
888 888 888 888 888 888 888 888 888 | |
888 88888b. 8888b. 88888b. 888888 .d88b. 888d888 888 .d88P 888 888 .d8888b 888888 .d8888b | |
888 888 "88b "88b 888 "88b 888 d8P Y8b 888P" 888 .od888P" 888 88888 888 88K 888 88K | |
888 888 888 888 .d888888 888 888 888 88888888 888 888 d88P" 888888 888 888 888 "Y8888b. 888 "Y8888b. | |
Y88b d88P 888 888 888 888 888 d88P Y88b. Y8b. 888 888 888" Y88b d88P 888 X88 Y88b. X88 | |
"Y8888P" 888 888 "Y888888 88888P" "Y888 "Y8888 888 8888888 888888888 "Y8888P88 888 88888P' "Y888 88888P' | |
888 | |
888 | |
888 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
createTutorial: function(req, res) { | |
/* | |
__ __ _ _ _ _ _ | |
\ \ / /_ _| (_)__| |__ _| |_(_)___ _ _ | |
\ V / _` | | / _` / _` | _| / _ \ ' \ | |
\_/\__,_|_|_\__,_\__,_|\__|_\___/_||_| | |
*/ | |
if (!_.isString(req.param('title'))) { | |
return res.badRequest(); | |
} | |
if (!_.isString(req.param('description'))) { | |
return res.badRequest(); | |
} | |
// Find the user that's adding a tutorial | |
User.findOne({ | |
id: req.session.userId | |
}).exec(function(err, foundUser){ | |
if (err) return res.negotiate; | |
if (!foundUser) return res.notFound(); | |
// Create the new tutorial in the tutorial model | |
Tutorial.create({ | |
title: req.param('title'), | |
description: req.param('description'), | |
owner: { username: foundUser.username }, | |
}).exec(function(err, createdTutorial){ | |
if (err) return res.negotate(err); | |
// Update the user to contain the new tutorial | |
foundUser.tutorials = []; | |
foundUser.tutorials.push({ | |
title: req.param('title'), | |
description: req.param('description'), | |
created: foundUser.createdAt, | |
updated: foundUser.updatedAt, | |
id: foundUser.id | |
}); | |
User.update({ | |
id: req.session.userId | |
}, { | |
tutorials: foundUser.tutorials | |
}) | |
.exec(function(err){ | |
if (err) return res.negotiate(err); | |
// return the new tutorial id | |
return res.json({id: createdTutorial.id}); | |
}); | |
}); | |
}); | |
}, |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
editTutorial: function(req, res) { | |
Tutorial.findOne({ | |
id: +req.param('id') | |
}).exec(function (err, foundTutorial){ | |
if (err) return res.negotiate(err); | |
if (!foundTutorial) return res.notFound(); | |
User.findOne({ | |
id: +req.session.userId | |
}).exec(function (err, foundUser) { | |
if (err) { | |
return res.negotiate(err); | |
} | |
if (!foundUser) { | |
sails.log.verbose('Session refers to a user who no longer exists- did you delete a user, then try to refresh the page with an open tab logged-in as that user?'); | |
return res.redirect('/tutorials'); | |
} | |
if (foundUser.username !== foundTutorial.owner.username) { | |
return res.redirect('/tutorials/'+foundTutorial.id); | |
} | |
return res.view('tutorials-detail-edit', { | |
me: { | |
gravatarURL: foundUser.gravatarURL, | |
username: foundUser.username, | |
admin: foundUser.admin | |
}, | |
tutorial: { | |
id: foundTutorial.id, | |
title: foundTutorial.title, | |
description: foundTutorial.description, | |
} | |
}); | |
}); | |
}); | |
}, |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
updateTutorial: function(req, res) { | |
// Validate parameters | |
if (!_.isString(req.param('title'))) { | |
return res.badRequest(); | |
} | |
if (!_.isString(req.param('description'))) { | |
return res.badRequest(); | |
} | |
User.findOne({ | |
id: req.session.userId | |
}).exec(function (err, foundUser){ | |
if (err) return res.negotiate(err); | |
if (!foundUser) return res.notFound(); | |
Tutorial.findOne({ | |
id: +req.param('id') | |
}) | |
.exec(function(err, foundTutorial){ | |
if (err) return res.negotiate(err); | |
if (!foundTutorial) return res.notFound(); | |
if (foundUser.username != foundTutorial.owner.username) { | |
return res.forbidden(); | |
} | |
// // We could also do it this way | |
// // Update the tutorial coercing the incoming id from a string to an integer using the unary `+` | |
// Tutorial.update({ | |
// id: +req.param('id') | |
// }, { | |
// title: req.param('title'), | |
// description: req.param('description') | |
// }).exec(function (err) { | |
// if (err) return res.negotiate(err); | |
// async.each(foundUser, function (user, next){ | |
// var cachedTutorial = _.find(foundUser.tutorials, { id: +req.param('id') }); | |
// if (!cachedTutorial) { | |
// return next(); | |
// } | |
// cachedTutorial.title = req.param('title'); | |
// cachedTutorial.description = req.param('description'); | |
// // update that array with the new values. | |
// User.update({ | |
// id: foundUser.id | |
// }, { | |
// tutorials: foundUser.tutorials | |
// }) | |
// .exec(function (err) { | |
// if (err) { return next(err); } | |
// return next(); | |
// }); | |
// }, function (err) { | |
// if (err) {return res.negotiate(err);} | |
// return res.ok(); | |
// }); | |
// }); | |
// Update the tutorial coercing the incoming id from a string to an integer using the unary `+` | |
Tutorial.update({ | |
id: +req.param('id') | |
}).set({ | |
title: req.param('title'), | |
description: req.param('description') | |
}).exec(function (err) { | |
if (err) return res.negotiate(err); | |
//Propagate updates to embedded (i.e. cached) arrays of tutorials on our user records. | |
// Find all user records | |
User.find().exec(function (err, users) { | |
if (err) { return res.negotiate(err); } | |
// Iterate through each user record in the users array | |
async.each(users, function (user, next){ | |
// Look to see whether the user's user.tutorials array contains the | |
// id of the tutorial that's being updated and create a reference | |
// named cachedTutorial if it contains the updated tutorial id. | |
var cachedTutorial = _.find(user.tutorials, { id: +req.param('id') }); | |
// Otherwise, keep moving on to the next user. | |
if (!cachedTutorial) { | |
return next(); | |
} | |
// update the reference which will also update user.tutorials | |
cachedTutorial.title = req.param('title'); | |
cachedTutorial.description = req.param('description'); | |
// We could also have written it this way | |
// var cachedTutorial = _.find(user.tutorials, function(tutorial){ | |
// if (tutorial.id === +req.param('id')) { | |
// tutorial.title = req.param('title'); | |
// tutorial.description = req.param('description'); | |
// } else { | |
// return next(); | |
// } | |
// }); | |
// If this user has the tutorial that's being updated in `user.tutorials` | |
// update that array with the new values. | |
User.update({ | |
id: user.id | |
}, { | |
tutorials: user.tutorials | |
}) | |
.exec(function (err) { | |
if (err) { return next(err); } | |
return next(); | |
}); | |
}, function (err) { | |
if (err) {return res.negotiate(err);} | |
return res.ok(); | |
}); | |
}); | |
}); | |
}); | |
}); | |
}, |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* User.js | |
* | |
* @description :: TODO: You might write a short summary of how this model works and what it represents here. | |
* @docs :: http://sailsjs.org/#!documentation/models | |
*/ | |
module.exports = { | |
attributes: { | |
email: { | |
type: 'string', | |
email: 'true', | |
unique: 'true' | |
}, | |
username: { | |
type: 'string', | |
unique: 'true' | |
}, | |
encryptedPassword: { | |
type: 'string' | |
}, | |
gravatarURL: { | |
type: 'string' | |
}, | |
deleted: { | |
type: 'boolean' | |
}, | |
admin: { | |
type: 'boolean' | |
}, | |
banned: { | |
type: 'boolean' | |
}, | |
passwordRecoveryToken: { | |
type: 'string' | |
}, | |
// tutorials: { | |
// type: 'json' | |
// }, | |
tutorials: { | |
collection: 'tutorial', | |
}, | |
ratings: { | |
collection: 'rating', | |
via: 'byUser' | |
}, | |
// Who is following me? | |
followers: { | |
collection: 'user', | |
via: 'following' | |
}, | |
// Who am I following? | |
following: { | |
collection: 'user', | |
via: 'followers' | |
}, | |
toJSON: function() { | |
var obj = this.toObject(); | |
delete obj.password; | |
delete obj.confirmation; | |
delete obj.encryptedPassword; | |
return obj; | |
} | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Tutorial.js | |
* | |
* @description :: TODO: You might write a short summary of how this model works and what it represents here. | |
* @docs :: http://sailsjs.org/#!documentation/models | |
*/ | |
module.exports = { | |
attributes: { | |
title: { | |
type: 'string' | |
}, | |
description: { | |
type: 'string' | |
}, | |
// owner: { | |
// type: 'json' | |
// }, | |
owner: { | |
model: 'user' | |
}, | |
// An array of video ids representing the manual (human) ordering of videos. | |
videoOrder: { | |
// e.g. | |
// [ | |
// 3 | |
// ] | |
type: 'json' | |
// (this is always ok because there will never be millions of videos per tutorial) | |
}, | |
videos: { | |
collection: 'video', | |
via: 'tutorialAssoc' | |
}, | |
ratings: { | |
collection: 'rating', | |
via: 'byTutorial' | |
} | |
} | |
}; | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
createTutorial: function(req, res) { | |
/* | |
__ __ _ _ _ _ _ | |
\ \ / /_ _| (_)__| |__ _| |_(_)___ _ _ | |
\ V / _` | | / _` / _` | _| / _ \ ' \ | |
\_/\__,_|_|_\__,_\__,_|\__|_\___/_||_| | |
*/ | |
if (!_.isString(req.param('title'))) { | |
return res.badRequest(); | |
} | |
if (!_.isString(req.param('description'))) { | |
return res.badRequest(); | |
} | |
// Find the user that's adding a tutorial | |
User.findOne({ | |
id: req.session.userId | |
}).exec(function(err, foundUser){ | |
if (err) return res.negotiate; | |
if (!foundUser) return res.notFound(); | |
Tutorial.create({ | |
title: req.param('title'), | |
description: req.param('description'), | |
owner: foundUser.id, | |
videoOrder: [], | |
}).exec(function(err, createdTutorial){ | |
if (err) return res.negotiate(err); | |
foundUser.tutorials.add(createdTutorial.id); | |
foundUser.save(function (err) { | |
if (err) return res.negotiate(err); | |
return res.json({id: createdTutorial.id}); | |
}); | |
}); | |
}); | |
}, |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
createTutorial: function(req, res) { | |
/* | |
__ __ _ _ _ _ _ | |
\ \ / /_ _| (_)__| |__ _| |_(_)___ _ _ | |
\ V / _` | | / _` / _` | _| / _ \ ' \ | |
\_/\__,_|_|_\__,_\__,_|\__|_\___/_||_| | |
*/ | |
if (!_.isString(req.param('title'))) { | |
return res.badRequest(); | |
} | |
if (!_.isString(req.param('description'))) { | |
return res.badRequest(); | |
} | |
// Find the user that's adding a tutorial | |
User.findOne({ | |
id: req.session.userId | |
}).exec(function(err, foundUser){ | |
if (err) return res.negotiate; | |
if (!foundUser) return res.notFound(); | |
Tutorial.create({ | |
title: req.param('title'), | |
description: req.param('description'), | |
owner: foundUser.id, | |
videoOrder: [], | |
}).exec(function(err, createdTutorial){ | |
if (err) return res.negotiate(err); | |
foundUser.tutorials.add(createdTutorial.id); | |
foundUser.save(function (err) { | |
if (err) return res.negotiate(err); | |
User.findOne({ | |
id: req.session.userId | |
}) | |
.populate('tutorials') | |
.exec(function (err, demoUser){ | |
if (err) return res.negotiate(err); | |
console.log('demoUser: ', demoUser); | |
Tutorial.findOne({ | |
id: createdTutorial.id | |
}) | |
.populate('owner') | |
.exec(function (err, demoTutorial){ | |
if (err) return res.negotiate(err); | |
console.log('demoTutorial: ', demoTutorial); | |
return res.json({id: createdTutorial.id}); | |
}); | |
}); | |
}); | |
}); | |
}); | |
}, |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* User.js | |
* | |
* @description :: TODO: You might write a short summary of how this model works and what it represents here. | |
* @docs :: http://sailsjs.org/#!documentation/models | |
*/ | |
module.exports = { | |
attributes: { | |
email: { | |
type: 'string', | |
email: 'true', | |
unique: 'true' | |
}, | |
username: { | |
type: 'string', | |
unique: 'true' | |
}, | |
encryptedPassword: { | |
type: 'string' | |
}, | |
gravatarURL: { | |
type: 'string' | |
}, | |
deleted: { | |
type: 'boolean' | |
}, | |
admin: { | |
type: 'boolean' | |
}, | |
banned: { | |
type: 'boolean' | |
}, | |
passwordRecoveryToken: { | |
type: 'string' | |
}, | |
// tutorials: { | |
// type: 'json' | |
// }, | |
// tutorials: { | |
// collection: 'tutorial', | |
// }, | |
tutorials: { | |
collection: 'tutorial', | |
via: 'owner' | |
}, | |
ratings: { | |
collection: 'rating', | |
via: 'byUser' | |
}, | |
// Who is following me? | |
followers: { | |
collection: 'user', | |
via: 'following' | |
}, | |
// Who am I following? | |
following: { | |
collection: 'user', | |
via: 'followers' | |
}, | |
toJSON: function() { | |
var obj = this.toObject(); | |
delete obj.password; | |
delete obj.confirmation; | |
delete obj.encryptedPassword; | |
return obj; | |
} | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
createTutorial: function(req, res) { | |
/* | |
__ __ _ _ _ _ _ | |
\ \ / /_ _| (_)__| |__ _| |_(_)___ _ _ | |
\ V / _` | | / _` / _` | _| / _ \ ' \ | |
\_/\__,_|_|_\__,_\__,_|\__|_\___/_||_| | |
*/ | |
if (!_.isString(req.param('title'))) { | |
return res.badRequest(); | |
} | |
if (!_.isString(req.param('description'))) { | |
return res.badRequest(); | |
} | |
// Find the user that's adding a tutorial | |
User.findOne({ | |
id: req.session.userId | |
}).exec(function(err, foundUser){ | |
if (err) return res.negotiate; | |
if (!foundUser) return res.notFound(); | |
Tutorial.create({ | |
title: req.param('title'), | |
description: req.param('description'), | |
owner: foundUser.id, | |
}) | |
.exec(function(err, createdTutorial){ | |
if (err) return res.negotiate(err); | |
return res.json({id: createdTutorial.id}); | |
}); | |
}); | |
}, |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
updateTutorial: function(req, res) { | |
// Validate parameters | |
if (!_.isString(req.param('title'))) { | |
return res.badRequest(); | |
} | |
if (!_.isString(req.param('description'))) { | |
return res.badRequest(); | |
} | |
// Update the tutorial coercing the incoming id from a string to an integer using the unary `+` | |
Tutorial.update({ | |
id: +req.param('id') | |
}, { | |
title: req.param('title'), | |
description: req.param('description') | |
}).exec(function (err) { | |
if (err) return res.negotiate(err); | |
return res.ok(); | |
}); | |
}, |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
tutorialDetail: function(req, res) { | |
Tutorial.findOne({ | |
id: req.param('id') | |
}) | |
.populate('owner') | |
.exec(function(err, foundTutorial){ | |
if (err) return res.negotiate(err); | |
if (!foundTutorial) return res.notFound(); | |
foundTutorial.owner = foundTutorial.owner.username; | |
// If not logged in set `me` property to `null` and pass the tutorial to the view | |
if (!req.session.userId) { | |
return res.view('tutorials-detail', { | |
me: null, | |
stars: foundTutorial.stars, | |
tutorial: foundTutorial | |
}); | |
} | |
User.findOne(req.session.userId) | |
.exec(function(err, user) { | |
if (err) return res.negotiate(err); | |
if (!user) { | |
sails.log.verbose('Session refers to a user who no longer exists- did you delete a user, then try to refresh the page with an open tab logged-in as that user?'); | |
return res.view('tutorials-detail', { | |
me: null | |
}); | |
} | |
// We'll provide `me` as a local to the profile page view. | |
// (this is so we can render the logged-in navbar state, etc.) | |
var me = { | |
gravatarURL: user.gravatarURL, | |
username: user.username, | |
admin: user.admin | |
}; | |
if (user.username === foundTutorial.owner) { | |
me.isMe = true; | |
return res.view('tutorials-detail', { | |
me: me, | |
showAddTutorialButton: true, | |
stars: foundTutorial.stars, | |
tutorial: foundTutorial | |
}); | |
} else { | |
return res.view('tutorials-detail', { | |
me: { | |
gravatarURL: user.gravatarURL, | |
username: user.username, | |
admin: user.admin | |
}, | |
showAddTutorialButton: true, | |
stars: foundTutorial.stars, | |
tutorial: foundTutorial | |
}); | |
} | |
}); | |
}); | |
}, |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
tutorialDetail: function(req, res) { | |
Tutorial.findOne({ | |
id: req.param('id') | |
}) | |
.populate('owner') | |
.populate('videos') | |
.exec(function(err, foundTutorial){ | |
if (err) return res.negotiate(err); | |
if (!foundTutorial) return res.notFound(); | |
foundTutorial.owner = foundTutorial.owner.username; | |
foundTutorial.created = DatetimeService.getTimeAgo({date: foundTutorial.createdAt}); | |
foundTutorial.updated = DatetimeService.getTimeAgo({date: foundTutorial.updatedAt}); | |
// If not logged in set `me` property to `null` and pass the tutorial to the view | |
if (!req.session.userId) { | |
return res.view('tutorials-detail', { | |
me: null, | |
stars: foundTutorial.stars, | |
tutorial: foundTutorial | |
}); | |
} | |
User.findOne(req.session.userId) | |
.exec(function(err, user) { | |
if (err) return res.negotiate(err); | |
if (!user) { | |
sails.log.verbose('Session refers to a user who no longer exists- did you delete a user, then try to refresh the page with an open tab logged-in as that user?'); | |
return res.view('tutorials-detail', { | |
me: null | |
}); | |
} | |
// We'll provide `me` as a local to the profile page view. | |
// (this is so we can render the logged-in navbar state, etc.) | |
var me = { | |
gravatarURL: user.gravatarURL, | |
username: user.username, | |
admin: user.admin | |
}; | |
if (user.username === foundTutorial.owner) { | |
me.isMe = true; | |
return res.view('tutorials-detail', { | |
me: me, | |
showAddTutorialButton: true, | |
stars: foundTutorial.stars, | |
tutorial: foundTutorial | |
}); | |
} else { | |
return res.view('tutorials-detail', { | |
me: { | |
gravatarURL: user.gravatarURL, | |
username: user.username, | |
admin: user.admin | |
}, | |
showAddTutorialButton: true, | |
stars: foundTutorial.stars, | |
tutorial: foundTutorial | |
}); | |
} | |
}); | |
}); | |
}, |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment