This commit is contained in:
David Arranz 2019-05-23 11:40:50 +02:00
parent bbc792ed33
commit 2a9ec3a346
12 changed files with 227 additions and 75 deletions

View File

@ -9,42 +9,51 @@ function buildContext(req, res) {
}
const defaultOptions = {
MODULE_NAME: 'default'
MODULE_NAME: 'default',
params: {
find: { includeAll: true },
findOne: { includeAll: true, paginate: { limit: 1, page: 1 } },
count: {},
}
}
const generateControllers = (service, extraControllers = {}, options = defaultOptions) => {
const generateControllers = (service, extraControllers = {}, options = {}) => {
const _options = {
...defaultOptions,
...options
};
const defaultControllers = {
find: async (req, res, next) => {
const params = extractParamsFromRequest(req, res);
find: async (req, res, next) => {
const params = extractParamsFromRequest(req, res, _options.params.find);
try {
const result = await service.fetchAll(params, buildContext(req, res));
return handleResultResponse(result.rows, result.count, params, res);
} catch (error) {
handleErrorResponse(options.MODULE_NAME, 'find', error, res)
handleErrorResponse(_options.MODULE_NAME, 'find', error, res)
}
},
findOne: async (req, res, next) => {
const params = extractParamsFromRequest(req, res);
const params = extractParamsFromRequest(req, res, _options.params.findOne);
try {
const result = await service.fetchOne(params, buildContext(req, res));
console.log(result);
return handleResultResponse(result, null, params, res, (result === null) ? httpStatus.NOT_FOUND : httpStatus.OK);
} catch (error) {
handleErrorResponse(options.MODULE_NAME, 'findOne', error, res)
handleErrorResponse(_options.MODULE_NAME, 'findOne', error, res)
}
},
count: async(req, res, next) => {
const params = extractParamsFromRequest(req, res);
const params = extractParamsFromRequest(req, res, _options.params.count);
try {
const result = await service.count(params, buildContext(req, res));
return handleResultResponse(result, null, params, res);
} catch (error) {
handleErrorResponse(options.MODULE_NAME, 'count', error, res)
handleErrorResponse(_options.MODULE_NAME, 'count', error, res)
}
},
@ -53,7 +62,7 @@ const generateControllers = (service, extraControllers = {}, options = defaultOp
const result = await service.create(req.body, buildContext(req, res));
return handleResultResponse(result, null, null, res, httpStatus.CREATED)
} catch (error) {
handleErrorResponse(options.MODULE_NAME, 'create', error, res)
handleErrorResponse(_options.MODULE_NAME, 'create', error, res)
}
},
@ -62,7 +71,7 @@ const generateControllers = (service, extraControllers = {}, options = defaultOp
const result = await service.update(req.params, req.body, buildContext(req, res));
return handleResultResponse(result, null, req.params, res, httpStatus.OK)
} catch (error) {
handleErrorResponse(options.MODULE_NAME, 'update', error, res)
handleErrorResponse(_options.MODULE_NAME, 'update', error, res)
}
},
@ -71,7 +80,7 @@ const generateControllers = (service, extraControllers = {}, options = defaultOp
const result = await service.delete(req.params, buildContext(req, res));
return handleResultResponse(result, null, req.params, res, httpStatus.NO_CONTENT);
} catch (error) {
handleErrorResponse(options.MODULE_NAME, 'delete', error, res)
handleErrorResponse(_options.MODULE_NAME, 'delete', error, res)
}
},
}

View File

@ -86,7 +86,7 @@ function setPaginationInfo(totalCount, res) {
// PUBLIC FUNCTIONS
////////////////////////////////////////////////////////////////////////////////
function extractParamsFromRequest(req, res) {
function extractParamsFromRequest(req, res, extraParams = {}) {
const result = {};
result.params = (req && req.params) ? req.params : null;
@ -98,7 +98,10 @@ function extractParamsFromRequest(req, res) {
})
}
return result;
return {
...result,
...extraParams
}
}

View File

@ -1,7 +1,79 @@
const _ = require('lodash');
function _debugModelInfo(model) {
if (!model.name)
return;
console.log("\n\n----------------------------------\n",
model.name,
"\n----------------------------------");
console.log("\nAttributes");
if (model.rawAttributes) {
for (let attr of Object.keys(model.rawAttributes)) {
console.log(model.name + '.' + attr);
}
}
console.log("\nAssociations");
if (model.associations) {
for (let assoc of Object.keys(model.associations)) {
console.log('as: ', model.associations[assoc].as, 'type: ', model.associations[assoc].associationType);
for (let accessor of Object.keys(model.associations[assoc].accessors)) {
console.log(accessor);
console.log(model.name + '.' + model.associations[assoc].accessors[accessor] + '()');
}
}
}
if (model.Instance && model.Instance.super_) {
console.log("\nCommon");
for (let func of Object.keys(model.Instance.super_.prototype)) {
if (func === 'constructor' || func === 'sequelize')
continue;
console.log(model.name + '.' + func + '()');
}
}
console.log("\n\n----------------------------------\n",
"END",
"\n----------------------------------");
return;
}
function getAssociationArrayFromModel(model) {
const result = [];
if (!model || typeof model.associations !== 'object') {
throw new Error("Model should have the 'associations' property.");
}
Object.keys(model.associations).forEach(key => result.push(key));
return result;
}
function modelAssociationsToArray(model) {
const result = [];
if (!model || typeof model.associations !== 'object') {
throw new Error("Model should be an object with the 'associations' property.");
}
Object.keys(model.associations).forEach((key) => {
result[key] = model.associations[key];
//result.push(key);
});
return result;
}
const parseParamsToFindOptions = (params) => {
const result = {};
// Include All
result.include = (params.includeAll) ? [{ all: true }] : [];
// Query
if (params.query) {
@ -52,63 +124,36 @@ const generateService = (model, extraMethods = {}, options = defaultOptions) =>
fetchAll: async (params, context) => {
const findOptions = parseParamsToFindOptions(params);
console.log(model);
return await model.findAndCountAll(findOptions);
},
fetchOne: async (params, context) => {
return await model.findOne({ where: { 'id': params.id } });
const findOptions = parseParamsToFindOptions(params);
return await model.findOne({
where: findOptions.where,
include: findOptions.include
});
},
count: async (params, context) => {
// Convert `params` object to filters compatible with Bookshelf.
//const filters = strapi.utils.models.convertParams('post', params);
return await model.count(params);
const findOptions = parseParamsToFindOptions(params);
return await model.count(findOptions);
},
create: async (values, context) => {
return await model.create(values);
return await model.create(data);
},
update: async (params, values, context) => {
// Extract values related to relational data.
const relations = _.pick(values, Post.associations.map(ast => ast.alias));
const data = _.omit(values, Post.associations.map(ast => ast.alias));
// Create entry with no-relational data.
const entry = await Post.forge(params).save(data);
// Create relational data and return the entry.
return Post.updateRelations(Object.assign(params, {
values: relations
}));
const findOptions = parseParamsToFindOptions(params);
return await model.update(values, findOptions)
},
delete: async (params, context) => {
const numAffectedRows = await model.destroy({ where: { 'id': params.id } });
const findOptions = parseParamsToFindOptions(params);
const numAffectedRows = await model.destroy(findOptions);
return (numAffectedRows > 0);
/*params.values = {};
Post.associations.map(association => {
switch (association.nature) {
case 'oneWay':
case 'oneToOne':
case 'manyToOne':
case 'oneToManyMorph':
params.values[association.alias] = null;
break;
case 'oneToMany':
case 'manyToMany':
case 'manyToManyMorph':
params.values[association.alias] = [];
break;
default:
}
});
await Post.updateRelations(params);
return Post.forge(params).destroy();*/
},
search: async (params, context) => {
@ -200,6 +245,7 @@ const generateService = (model, extraMethods = {}, options = defaultOptions) =>
module.exports = {
_debugModelInfo,
generateService,
parseParamsToFindOptions,
defaultOptions

View File

@ -1,7 +1,10 @@
'use strict';
const { extractParamsFromRequest, handleErrorResponse, handleResultResponse } = require('../../helpers/controller.helper');
const generateControllers = require('../../core/controllers');
const models = require('../../core/models');
const blogService = require('./blog.service');
const generateCommentService = require('../comments/comment.service');
// Module Name
@ -13,9 +16,29 @@ const MODULE_NAME = '[blog.controller]';
// Success Messages
//const VG_CT_VIDEOGAME_DELETED_SUCCESSFULLY = 'Videogame deleted successfully';
const blogCommentsService = generateCommentService(models.Post.Comments);
const controllerOptions = { MODULE_NAME };
const extraControllers = {};
const controllerOptions = {
MODULE_NAME,
params: {
find: { includeAll: true },
findOne: { includeAll: true, paginate: { limit: 1, page: 1 } },
count: {},
}
};
const extraControllers = {
getPostComments: async (req, res, next) => {
const params = extractParamsFromRequest(req, res, controllerOptions.params.find);
try {
const result = await blogCommentsService.fetchAll(params, {});
return handleResultResponse(result.rows, result.count, params, res);
} catch (error) {
handleErrorResponse(controllerOptions.MODULE_NAME, 'find', error, res)
}
},
};
module.exports = generateControllers(blogService, extraControllers, controllerOptions);

View File

@ -10,10 +10,9 @@ const FieldMiddleware = require('../../middlewares/fields');
const blogController = require('./blog.controller')
routes.get('/posts',
isLoggedUser,
routes.get('/posts', isLoggedUser,
FieldMiddleware.middleware({
invalidFields: ['user', 'created']
invalidFields: ['user', 'createdAt']
}),
PaginateMiddleware.middleware(),
SortMiddleware.middleware({ default: "date" }),
@ -21,8 +20,7 @@ routes.get('/posts',
routes.post('/posts', isAdministratorUser, blogController.create);
routes.get('/posts/:id',
isLoggedUser,
routes.get('/posts/:id', isLoggedUser,
FieldMiddleware.middleware({
invalidFields: ['updatedAt', 'createdAt']
}),
@ -34,4 +32,10 @@ routes.get('/posts/:id',
routes.put('/posts/:id', isAdministratorUser, blogController.update);
routes.delete('/posts/:id', isAdministratorUser, blogController.delete);
routes.get('/posts/:id/comments', isLoggedUser,
PaginateMiddleware.middleware(),
SortMiddleware.middleware({ default: "date" }),
blogController.getPostComments);
module.exports = routes;

View File

@ -2,21 +2,29 @@
'use strict';
const _ = require('lodash');
const { generateService, parseParamsToFindOptions } = require('../../helpers/service.helper');
const { generateService, parseParamsToFindOptions, _debugModelInfo } = require('../../helpers/service.helper');
const models = require('../../core/models');
const extraMethods = {
fetchOne: async (params, context) => {
/*fetchOne: async (params, context) => {
const findOptions = parseParamsToFindOptions(params);
console.log(findOptions);
const result = await models.Post.findByPk(findOptions.query.id, {
include: [{ all: true }]
});
console.log(result);
return result;
},
},*/
create: async (values, context) => {
const { Categories, ...data } = values;
return models.sequelize.transaction(async transaction => {
const result = await models.Post.create(data, { transaction });
if (Categories) {
await result.setCategories(Categories, { transaction });
}
return result;
});
},
}

View File

@ -11,7 +11,7 @@ module.exports = function (sequelize, DataTypes) {
},
sort: {
type: DataTypes.INTEGER,
defaultValue: 0,
defaultValue: 0,
allowNull: false,
}
}, {
@ -20,9 +20,9 @@ module.exports = function (sequelize, DataTypes) {
timestamps: false
});
Category.beforeCreate((category) => {
/*Category.beforeCreate((category) => {
//category.dataValues.id = Math.floor(Math.random() * (999 - 8)) + 8;
})
})*/
Category.associate = function (models) {
Category.Posts = Category.belongsToMany(models.Post, {

View File

@ -2,12 +2,12 @@ const routes = require('express').Router();
const { isAdministratorUser, isLoggedUser } = require('../../middlewares/accessValidator');
/*const PaginateMiddleware = require('../../middlewares/paginate');
const SortMiddleware = require('../../middlewares/sort');
const FieldMiddleware = require('../../middlewares/fields');*/
const SortMiddleware = require('../../middlewares/sort');
const categoryController = require('./category.controller');
routes.get('/categories', isLoggedUser, categoryController.find);
routes.get('/categories', isLoggedUser, SortMiddleware.middleware({ default: "name" }), categoryController.find);
routes.get('/categories/:id', isLoggedUser, categoryController.findOne);
routes.post('/categories/', isAdministratorUser, categoryController.create);

View File

@ -11,7 +11,7 @@ module.exports = function (sequelize, DataTypes) {
foreignKey: true
}
}, {
tableName: 'post-category',
tableName: 'post_category',
freezeTableName: true,
timestamps: false
});

View File

@ -35,7 +35,7 @@ module.exports = function (sequelize, DataTypes) {
through: models.PostCategory,
foreignKey: 'postId'
});
//Post.Comments = Post.hasMany(models.PostComment, { foreignKey: 'postId' });
Post.Comments = Post.hasMany(models.Comment, { foreignKey: 'postId' });
//Post.Reactions = Post.hasMany(models.PostReaction, { foreignKey: 'postId' });
//Post.User = Post.belongsTo(models.User, { foreignKey: 'userId' });
};

View File

@ -0,0 +1,49 @@
module.exports = function (sequelize, DataTypes) {
const Comment = sequelize.define('Comment', {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true
},
entityType: {
field: 'type',
type: DataTypes.STRING,
allowNull: false
},
entity: {
type: DataTypes.VIRTUAL(DataTypes.UUID, ['conferenceId', 'speakerId', 'postId']),
},
content: {
type: DataTypes.STRING,
allowNull: false
},
user: {
type: DataTypes.VIRTUAL(DataTypes.UUID, ['userId']),
},
/*conference: {
type: DataTypes.VIRTUAL(DataTypes.UUID, ['conferenceId']),
},*/
post: {
type: DataTypes.VIRTUAL(DataTypes.UUID, ['postId']),
},
/*speaker: {
type: DataTypes.VIRTUAL(DataTypes.UUID, ['speakerId']),
},*/
}, {
tableName: 'comments',
freezeTableName: true,
timestamps: true,
});
Comment.associate = function (models) {
Comment.User = Comment.belongsTo(models.User, { foreignKey: 'userId', constraints: false });
//Comment.Conference = Comment.belongsTo(models.Conference, { foreignKey: 'conferenceId', constraints: false });
Comment.Post = Comment.belongsTo(models.Post, { foreignKey: 'postId', constraints: false });
//Comment.Speaker = Comment.belongsTo(models.Speaker, { foreignKey: 'speakerId', constraints: false });
};
return Comment;
};

View File

@ -0,0 +1,10 @@
/* global Post */
'use strict';
const _ = require('lodash');
const { generateService, parseParamsToFindOptions } = require('../../helpers/service.helper');
const models = require('../../core/models');
const extraMethods = {}
module.exports = (model) => generateService(model, extraMethods);