diff --git a/framework/serializers/questions.js b/framework/serializers/questions.js index 5f1c5e9..184a55e 100644 --- a/framework/serializers/questions.js +++ b/framework/serializers/questions.js @@ -12,12 +12,19 @@ module.exports = function (included = [], type, config) { id: relationship.id } } + }, + tags: { + valueForRelationship (relationship) { + return { + id: relationship.id + } + } } } } const options = { - attributes: ['title', 'description', 'difficulty' ,'user', 'choices', 'createdBy'], + attributes: ['title', 'description', 'difficulty' ,'user', 'choices', 'tags', 'createdBy'], meta: { pagination: function (record) { return record.pagination @@ -33,6 +40,11 @@ module.exports = function (included = [], type, config) { attributes: ['title', 'description', 'positiveWeight' ,'negativeWeight', 'question'], included: included.includes('choices') }, + tags: { + ref: 'id', + attributes: ['name'], + included: included.includes('tags') + }, ...config } diff --git a/framework/serializers/tags.js b/framework/serializers/tags.js new file mode 100644 index 0000000..21a5f58 --- /dev/null +++ b/framework/serializers/tags.js @@ -0,0 +1,17 @@ +module.exports = function (included = [], type, config) { + if (typeof type === 'object') { + config = type + } + + const options = { + attributes: ['name'], + meta: { + pagination: function (record) { + return record.pagination + } + }, + ...config + } + + return options +} \ No newline at end of file diff --git a/migrations/20190521182844-createTags.js b/migrations/20190521182844-createTags.js new file mode 100644 index 0000000..be3f1a9 --- /dev/null +++ b/migrations/20190521182844-createTags.js @@ -0,0 +1,36 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + queryInterface.createTable('tags', { + id: { + type:Sequelize.INTEGER, + primaryKey:true, + autoIncrement: true + }, + name: { + type: Sequelize.STRING, + allowNull: false + }, + createdById: { + type: Sequelize.INTEGER, + allowNull: false + }, + createdAt: { + type: Sequelize.DATE, + allowNull: false + }, + updatedAt: { + type: Sequelize.DATE, + allowNull: false + }, + deletedAt: { + type: Sequelize.DATE + } + }) + }, + + down: (queryInterface, Sequelize) => { + queryInterface.dropTable('tags') + } +}; diff --git a/migrations/20190521183150-createQuestionTags.js b/migrations/20190521183150-createQuestionTags.js new file mode 100644 index 0000000..2685508 --- /dev/null +++ b/migrations/20190521183150-createQuestionTags.js @@ -0,0 +1,36 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + queryInterface.createTable('question_tags', { + id:{ + type:Sequelize.INTEGER, + primaryKey:true, + autoIncrement: true + }, + tagId: { + type: Sequelize.INTEGER, + allowNull: false + }, + questionId: { + type: Sequelize.INTEGER, + allowNull: false + }, + createdAt: { + type: Sequelize.DATE, + allowNull: false + }, + updatedAt: { + type: Sequelize.DATE, + allowNull: false + }, + deletedAt: { + type: Sequelize.DATE + } + }) + }, + + down: (queryInterface, Sequelize) => { + queryInterface.dropTable('question_tags') + } +}; diff --git a/models/questionTags.js b/models/questionTags.js new file mode 100644 index 0000000..3196279 --- /dev/null +++ b/models/questionTags.js @@ -0,0 +1,14 @@ +'use-strict' +module.exports = (Sequelize, DataTypes) => { + const questionTags = Sequelize.define('question_tags', { + id:{ + type:DataTypes.INTEGER, + primaryKey:true, + autoIncrement: true + } + }, { paranoid: true }) + + questionTags.associate = function (models) {} + + return questionTags +} \ No newline at end of file diff --git a/models/questions.js b/models/questions.js index 224dfae..3148d87 100644 --- a/models/questions.js +++ b/models/questions.js @@ -27,8 +27,7 @@ module.exports = (sequelize, DataTypes) => { questions.hasMany(models.choices) questions.belongsTo(models.users,{foreignKey: 'updatedById'}) questions.belongsToMany(models.quizzes, {through: models.quizQuestions}) - - + questions.belongsToMany(models.tags, {through: models.question_tags}) }; return questions; }; \ No newline at end of file diff --git a/models/tags.js b/models/tags.js new file mode 100644 index 0000000..aee5951 --- /dev/null +++ b/models/tags.js @@ -0,0 +1,16 @@ +'use-strict' +module.exports = (Sequelize, DataTypes) => { + const tags = Sequelize.define('tags', { + name: { + type: DataTypes.STRING, + allowNull: false + } + }, { paranoid: true }) + + tags.associate = function(models) { + tags.belongsTo(models.users,{foreignKey: 'createdById'}) + tags.belongsToMany(models.questions, {through: models.question_tags}) + } + + return tags +} \ No newline at end of file diff --git a/routes/api/index.js b/routes/api/index.js index 38ceb10..ec8d5ed 100644 --- a/routes/api/index.js +++ b/routes/api/index.js @@ -2,12 +2,14 @@ const questions = require('./questions') const choices = require('./choices') const users = require('./users') const quiz = require('./quiz') +const tags = require('./tags') const Router = require('express').Router() Router.use('/questions', questions) Router.use('/choices', choices) Router.use('/users', users) Router.use('/quizzes', quiz) +Router.use('/tags', tags) module.exports = Router \ No newline at end of file diff --git a/routes/api/questions/controller.js b/routes/api/questions/controller.js index 3806714..5c66ec7 100644 --- a/routes/api/questions/controller.js +++ b/routes/api/questions/controller.js @@ -10,6 +10,32 @@ class QuestionsController extends BaseController { this.submitQuestion = this.submitQuestion.bind(this) } + async handleUpdateById(req, res) { + try { + const modelObj = await this.deserialize(req.body) + + // set updatedBy + modelObj.updatedById = req.user.id + + await DB.question_tags.bulkCreate(modelObj.tags.map(tag => ({ + tagId: tag.id, + questionId: req.params.id + }))) + + await this._model.update(modelObj, { + where: { + id: req.params.id + } + }) + const result = await this._model.findById(req.params.id, { + include: this.generateIncludeStatement() + }) + res.json(this.serialize(result)) + } catch (err) { + rrthis.handleError(err, res) + } + } + async handleGetAnswers (req, res) { const { id } = req.params diff --git a/routes/api/tags/index.js b/routes/api/tags/index.js new file mode 100644 index 0000000..3984180 --- /dev/null +++ b/routes/api/tags/index.js @@ -0,0 +1,17 @@ +const BaseController = require('../../../framework/Controller.class') +const routes = require('express').Router() +const DB = require('../../../models') + +const passport = require('../../../passport/index') +const { adminOnly } = require('../../../passport/middlewares') + +const controller = new BaseController(DB.tags) + +routes.use(passport.authenticate('bearer', {session: false}), adminOnly) + +routes.get('/', controller.handleQuery) +routes.get('/:id', controller.handleQueryById) +routes.post('/', controller.handleCreate) +routes.patch('/:id', controller.handleUpdateById) + +module.exports = routes;