Search code examples
node.jspostgresqlmodel-view-controllersequelize.js

How to implement active MVC model in Sequelize


I'm working on NodeJS + Sequelize app. Right now I have all my logic in controllers but I've been told that it is the wrong way (Fat Stupid Ugly Controllers). Here is my controller file:

const Deals = require('../models').deals;

module.exports = {
  createDeal: (req, res, next) => {
    const { description, category, open_time, close_time, property_id } = req.body;
    return Deals
    .create({ description, category, open_time, close_time, property_id })
    .then(deal => res.status(200).json({ status: 'Created one property', deal }))
    .catch(error => console.log(error));
  },

  getAllDeals: (req, res, next) => {
    return Deals
    .findAll({paranoid: false})
    .then(deals => res.status(200).json({ status: 'Retrieved all deals', deals }))
    .catch(error => console.log(error));
  },

  getSingleDeal: (req, res, next) => {
    const { id } = req.params;
    return Deals
    .findById(id)
    .then(deal => res.status(200).json({ status: 'Retrieved one deal', deal }))
    .catch(error => console.log(error));
  },

  updateDeal: (req, res, next) => {
    const { id } = req.params;
    const { description, category, open_time, close_time } = req.body;
    return Deals
    .findById(id)
    .then(deal => {
      if (!deal) {
        return res.status(404).send({ message: 'Deal not found' })
      }
      return deal
      .update({
        description: description,
        category: category,
        open_time: open_time,
        close_time: close_time
      })
      .then(deal => res.status(200).json({ status: 'Updated one deal', deal }))
      .catch(error => console.log(error));
    })
    .catch(error => console.log(error));
  },

  destroyDeal: (req, res, next) => {
    const { id } = req.params;
    return Deals
    .findById(id)
    .then(deal => {
      if (!deal) {
        return res.status(404).send({ message: 'Deal not found' })
      }
      return deal
      .destroy()
      .then(() =>  res.status(200).json({ status: 'Deleted one deal', deal }))
      .catch(error => console.log(error));
    })
  }
}

Here is the model file that I have:

'use strict';
module.exports = (sequelize, DataTypes) => {
  const Deals = sequelize.define('deals', {
    description: {
      allowNull: false,
      type: DataTypes.STRING
    },
    category: {
      allowNull: false,
      type: DataTypes.STRING
    },
    open_time: {
      allowNull: false,
      type: DataTypes.STRING
    },
    close_time: {
      allowNull: false,
      type: DataTypes.STRING
    },
    property_id: {
      allowNull: false,
      type: DataTypes.INTEGER
    }
  }, {
    timestamps: true,
    paranoid: true
  });
  Deals.associate = function(models) {
    // associations can be defined here
    Deals.belongsTo(models.properties, {
      foreignKey: 'property_id',
      onDelete: 'CASCADE'
    })
  };
  return Deals;
};

So, I've been told that my updateDeal() method is wrong because it makes more than one request to the model or database, when it should be only "getting and analyzing request from the user and choosing the next step (like sending it to other elements of the system)". So, I'm supposed to bring all the logic from the controller to my models functions. I'd like to have somebody's explanation on how it works or some code example.


Solution

  • I was able to change it. This is from my controller:

    updateDeal: (req, res, next) => {
        const { id } = req.params;
        return Deals
          .updateById(id, req.body)
          .then(deal => res.status(200).json({ status: 'Updated one deal', deal }))
          .catch(error => {
            return res.status(400).send({message: error.message})
          });
      }
    

    This is from the model:

    Deals.updateById = function(id, data){
        return Deals
          .findById(id)
          .then(deal => {
            if (!deal) {
              throw Error('Deal Not Found')
            }
            return deal
            .update(data, {fields: Object.keys(data)})
          })
    
      }
      return Deals;