diff --git a/app.js b/app.js index 66e7fb4..2cd3c09 100644 --- a/app.js +++ b/app.js @@ -34,6 +34,7 @@ app.use(cors()) app.use('/', require('./routes/vegetableTypes')(passport)) app.use('/', require('./routes/vegetables')(passport)) +app.use('/', require('./routes/properties')(passport)) app.use('/', require('./routes/user')(passport)) app.use(function (req, res, next) { diff --git a/middleware/Properties.js b/middleware/Properties.js new file mode 100644 index 0000000..b26a0ab --- /dev/null +++ b/middleware/Properties.js @@ -0,0 +1,92 @@ +const properties = require('../models').properties + +class Properties { + static getAll (req, callback) { + properties.findAndCountAll({ + order: [ + ['name', 'ASC'] + ] + }) + .then(items => { + if (!items) { + callback(new Error('No property found'), 204) + return false + } + callback(null, items) + }) + .catch((e) => { + callback(e, null) + }) + } + + createOne (req, callback) { + properties.create(req.body) + .then(item => { + callback(null, item) + }) + .catch(e => { + callback(e, null) + }) + } + + static getOne (req, callback) { + properties.findById( + req.params.propertyId + ) + .then(item => { + if (!item) { + callback(new Error('Property not found'), 404) + return false + } + callback(null, item) + }) + .catch((e) => { + callback(e, null) + }) + } + + patchOne (req, callback) { + Properties.getOne(req, (err, item) => { + if (err) { + callback(err, item) + return false + } + + item.update(req.body) + .then(animal => { + callback(null, animal) + }) + .catch(e => { + callback(e, null) + }) + }) + } + + deleteOne (req, callback) { + Properties.getOne(req, (err, item) => { + if (err) { + callback(err, item) + return false + } + + properties.destroy({ + where: { + id: req.params.propertyId + } + }) + .then(deleted => { + if (deleted === 0) { + callback(new Error('Error when trying to delete item')) + return false + } + + callback(null, null) + }) + .catch(e => { + callback(e, null) + }) + }) + } +} + +module.exports = Properties diff --git a/middleware/Vegetables.js b/middleware/Vegetables.js index 695ce1a..0a4a351 100644 --- a/middleware/Vegetables.js +++ b/middleware/Vegetables.js @@ -1,4 +1,5 @@ const vegetables = require('../models').vegetables +const models = require('../models') const VegetableTypes = require('./VegetableTypes') const uuid = require('uuid/v4') const multer = require('multer') @@ -176,7 +177,15 @@ class Vegetables { vegetableTypeId: req.params.vegetableTypesId, id: req.params.vegetablesId }, - include: ['Type', 'Pictures'] + include: [ + 'Type', + 'Pictures', + { + model: models.vegetableProperties, + as: 'Properties', + include: ['Property'] + } + ] }) .then(item => { if (!item) { diff --git a/migrations/20181002071412-create-properties.js b/migrations/20181002071412-create-properties.js new file mode 100644 index 0000000..88aa213 --- /dev/null +++ b/migrations/20181002071412-create-properties.js @@ -0,0 +1,27 @@ +'use strict'; +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('properties', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + name: { + type: Sequelize.STRING + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }); + }, + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('properties'); + } +}; diff --git a/migrations/20181002073641-create-vegetable-properties.js b/migrations/20181002073641-create-vegetable-properties.js new file mode 100644 index 0000000..98df0d5 --- /dev/null +++ b/migrations/20181002073641-create-vegetable-properties.js @@ -0,0 +1,32 @@ +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('vegetableProperties', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + vegetableId: { + type: Sequelize.INTEGER + }, + propertyId: { + type: Sequelize.INTEGER + }, + value: { + type: Sequelize.TEXT + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }) + }, + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('vegetableProperties') + } +} diff --git a/models/properties.js b/models/properties.js new file mode 100644 index 0000000..c47ff1d --- /dev/null +++ b/models/properties.js @@ -0,0 +1,9 @@ +module.exports = (sequelize, DataTypes) => { + const Properties = sequelize.define('properties', { + name: DataTypes.STRING + }, {}) + Properties.associate = function (models) { + // associations can be defined here + } + return Properties +} diff --git a/models/vegetable_properties.js b/models/vegetable_properties.js new file mode 100644 index 0000000..015ce9a --- /dev/null +++ b/models/vegetable_properties.js @@ -0,0 +1,26 @@ +module.exports = (sequelize, DataTypes) => { + const vegetableProperties = sequelize.define('vegetableProperties', { + vegetableId: { + type: DataTypes.INTEGER, + references: 'vegetables', + referencesKey: 'id' + }, + propertyId: { + type: DataTypes.INTEGER, + references: 'properties', + referencesKey: 'id' + }, + value: DataTypes.TEXT + }, {}) + vegetableProperties.associate = function (models) { + vegetableProperties.hasOne(models.vegetables, { + as: 'Vegetable', + foreignKey: 'id' + }) + vegetableProperties.hasOne(models.properties, { + as: 'Property', + foreignKey: 'id' + }) + } + return vegetableProperties +} diff --git a/models/vegetables.js b/models/vegetables.js index 157f3d4..70a1abb 100644 --- a/models/vegetables.js +++ b/models/vegetables.js @@ -21,6 +21,11 @@ module.exports = (sequelize, DataTypes) => { foreignKey: 'vegetableId', onDelete: 'cascade' }) + vegetables.hasMany(models.vegetableProperties, { + as: 'Properties', + foreignKey: 'vegetableId', + onDelete: 'cascade' + }) } return vegetables } diff --git a/routes/properties.js b/routes/properties.js new file mode 100644 index 0000000..df2f2a6 --- /dev/null +++ b/routes/properties.js @@ -0,0 +1,75 @@ +const express = require('express') +const router = express.Router() +const Properties = require('../middleware/Properties') + +module.exports = function (passport) { + const basePath = '/api/properties/' + const itemPath = basePath + ':propertyId' + + router.route(basePath) + .get( + function (req, res) { + Properties.getAll(req, function (err, items) { + if (err) { + res.status(items || 500).send(err.message) + } else { + res.status(200).json(items) + } + }) + } + ) + .post( + passport.authenticate(['basic-auth']), + function (req, res) { + const property = new Properties() + property.createOne(req, function (err, item) { + if (err) { + res.status(item || 500).send(err.message) + } else { + res.status(201).json(item) + } + }) + } + ) + + router.route(itemPath) + .get( + function (req, res) { + Properties.getOne(req, function (err, item) { + if (err) { + res.status(item || 500).send(err.message) + } else { + res.status(200).json(item) + } + }) + } + ) + .patch( + passport.authenticate(['basic-auth']), + function (req, res) { + const property = new Properties() + property.patchOne(req, function (err, item) { + if (err) { + res.status(item || 500).send(err.message) + } else { + res.status(200).json(item) + } + }) + } + ) + .delete( + passport.authenticate(['basic-auth']), + function (req, res) { + const property = new Properties() + property.deleteOne(req, function (err, item) { + if (err) { + res.status(item || 500).send(err.message) + } else { + res.status(200).json(item) + } + }) + } + ) + + return router +}