Skip to content

Instantly share code, notes, and snippets.

@sailsinaction
Last active May 21, 2016 21:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sailsinaction/f5694bfed9a552d56c5e7492dcc871ad to your computer and use it in GitHub Desktop.
Save sailsinaction/f5694bfed9a552d56c5e7492dcc871ad to your computer and use it in GitHub Desktop.
Chapter 12 - Gists
.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
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});
});
});
});
},
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,
}
});
});
});
},
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();
});
});
});
});
});
},
/**
* 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;
}
}
};
/**
* 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'
}
}
};
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});
});
});
});
},
/**
* 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;
}
}
};
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});
});
});
},
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();
});
},
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
});
}
});
});
},
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