【问题标题】:sequelize model's .create() method seems to have gone missingsequelize model .create() 方法似乎不见了
【发布时间】:2018-04-09 14:10:20
【问题描述】:

所以我有一个用 express.js 构建的小型 REST API,并且我已经将其重构为几个文件,因为我想这样做,但在此过程中,我的模型的 .create() 方法似乎有'消失'。 (顺便说一句,我是 JS 新手)

// carrot.js
const Sequelize = require('sequelize');

const carrotModel = {
    id: {
        type: Sequelize.UUID,
        primaryKey: true,
        defaultValue: Sequelize.UUIDV4
    },
    name: {
        type: Sequelize.STRING,
        allowNull: false,
        unique: true
    },
    color_id: {
        type: Sequelize.INTEGER,
        defaultValue: 255
    },
    createdAt: {
        type: Sequelize.INTEGER,
        allowNull: false
    },
    updatedAt: {
        type: Sequelize.INTEGER,
        allowNull: false
    }
};

module.exports = {
    carrotModel: carrotModel
}
==================================================
// db.js
const Sequelize = require('sequelize');

const AssociateModel = require('./associate').associateModel;
const CarrotModel = require('./carrot').carrotModel;
const CategoryModel = require('./category').categoryModel;
const ColorModel = require('./color').colorModel;

let connObj = new Sequelize(
    'db', 
    'username', 
    'password', {
        host: 'localhost',
        dialect: 'sqlite',
        storage: 'tempstorage.db'
    }, {timestamps: false});

let associate = connObj.define('associate', AssociateModel);
let carrot = connObj.define('carrot', CarrotModel);
let color = connObj.define('color', ColorModel);

let category = connObj.define('category', CategoryModel);
category.hasOne(color, {as: 'foregroundColor'});
category.hasOne(color, {as: 'backgroundColor'});

connObj.sync().then(() => {
    console.log('all tables created');
})

module.exports = {
    Color: color,
    Category: category,
    Associate: associate,
    Carrot: carrot,
}
==================================================
// genericModelActions.js
module.exports = {
    getAll: (model) => {
        return model.findAll();
    },
    getSpecific: (model, data) => {
        return model.findById(req.params.modelId);
    },
    createModelInstance: (model, data) => {
        return model.create(...data);
    },
    updateModelInstance: (model, data) => {
        return model.update(...data, {where: {id: data.id}});
    },
    deleteModelInstance: (model, modelId) => {
        return model.destroy({where: {id: modelId}});
    }
}
==================================================
// carrotController.js
const generics = require('./genericModelActions');
const Carrot = require('../models/db').Carrot;

module.exports = {
    getAllCarrots: (req, res, next) => {
        generics
            .getAll(Carrot)
            .then(carrots => {
                res.send({results: carrots});
            })
            .catch(err => {
                res.send({error: error});
            });
    },

    getSpecificCarrot: (req, res, next) => {
        generics
            .getSpecific(Carrot, req.params.carrotId)
            .then(carrots => {
                res.send({results: carrots});
            })
            .catch(err => {
                res.send({error: error});
            });
    },

    createCarrot: (req, res, next) => {
        console.log(Object.getOwnPropertyNames(Carrot));
        console.log(Carrot.prototype);
        req.body.createdAt = +Date.now()
        req.body.updatedAt = +Date.now()
        generics
             .createModelInstance(Carrot, req.body)
             .then(carrots => {
                 res.send({results: carrots})
             });
    },

    updateCarrot: (req, res, next) => {
        req.body.updatedAt = +Date.now();
        generics.update(Carrot, req.body)
    },
    deleteCarrot: (req, res, next) => {
    }
}
==================================================
// carrotRoutes.js
var express = require('express');
var router = express.Router();

var controller = require('../controllers/carrotController');

router.get('/', controller.getAllCarrots);
// TODO: Change this to POST to accommodate more complex search queries.
router.get('/:carrotId', controller.getSpecificCarrot);
router.post('/', controller.createCarrot);
router.patch('/', controller.updateCarrot);
router.delete('/', controller.deleteCarrot);

module.exports = router;
==================================================
const express = require('express');

const indexRouter = require('./routes/index');
const booksRouter = require('./routes/bookRoutes');
const categoriesRouter = require('./routes/categoryRoutes');
const carrotsRouter = require('./routes/carrotRoutes');

const sql = require('./models/db');

const app = express();

// view engine setup
app.use(express.json());
app.use(express.urlencoded({ extended: false }));

// custom model route setup
app.use('/', indexRouter);
app.use('/books', booksRouter);
app.use('/categories', categoriesRouter);
app.use('/carrots', carrotsRouter);

// sql.sync().then(() => {
//   app.listen(3000, () => {
//     console.log('basic app listening on 3000');
//   })
// });

app.listen(3000, () => {
  console.log('listening on 3000');
})
==================================================
// OUTPUT
output of Object.getOwnPropertyNames(Carrot) (in carrotController.js) = 
   [ 'length',
  'prototype',
  'name',
  'sequelize',
  'options',
  'associations',
  'underscored',
  'tableName',
  '_schema',
  '_schemaDelimiter',
  'rawAttributes',
  'primaryKeys',
  '_timestampAttributes',
  '_readOnlyAttributes',
  '_hasReadOnlyAttributes',
  '_isReadOnlyAttribute',
  '_dataTypeChanges',
  '_dataTypeSanitizers',
  '_booleanAttributes',
  '_dateAttributes',
  '_hstoreAttributes',
  '_rangeAttributes',
  '_jsonAttributes',
  '_geometryAttributes',
  '_virtualAttributes',
  '_defaultValues',
  'fieldRawAttributesMap',
  'fieldAttributeMap',
  'uniqueKeys',
  '_hasBooleanAttributes',
  '_isBooleanAttribute',
  '_hasDateAttributes',
  '_isDateAttribute',
  '_hasHstoreAttributes',
  '_isHstoreAttribute',
  '_hasRangeAttributes',
  '_isRangeAttribute',
  '_hasJsonAttributes',
  '_isJsonAttribute',
  '_hasVirtualAttributes',
  '_isVirtualAttribute',
  '_hasGeometryAttributes',
  '_isGeometryAttribute',
  '_hasDefaultValues',
  'attributes',
  'tableAttributes',
  'primaryKeyAttributes',
  'primaryKeyAttribute',
  'primaryKeyField',
  '_hasPrimaryKeys',
  '_isPrimaryKey',
  'autoIncrementAttribute',
  '_scope',
  '_scopeNames' ]

Output of console.log(Carrot.prototype) (located in carrotController.js) = 
carrot {
  _customGetters: {},
  _customSetters: {},
  validators: {},
  _hasCustomGetters: 0,
  _hasCustomSetters: 0,
  rawAttributes: 
   { id: 
      { type: UUID {},
        primaryKey: true,
        defaultValue: UUIDV4 {},
        Model: carrot,
        fieldName: 'id',
        _modelAttribute: true,
        field: 'id' },
     name: 
      { type: [Object],
        allowNull: false,
        unique: true,
        Model: carrot,
        fieldName: 'name',
        _modelAttribute: true,
        field: 'name' },
     color_id: 
      { type: [Object],
        defaultValue: 255,
        Model: carrot,
        fieldName: 'color_id',
        _modelAttribute: true,
        field: 'color_id' },
     createdAt: 
      { type: [Object],
        allowNull: false,
        Model: carrot,
        fieldName: 'createdAt',
        _modelAttribute: true,
        field: 'createdAt' },
     updatedAt: 
      { type: [Object],
        allowNull: false,
        Model: carrot,
        fieldName: 'updatedAt',
        _modelAttribute: true,
        field: 'updatedAt' } },
  attributes: [ 'id', 'name', 'color_id', 'createdAt', 'updatedAt' ],
  _isAttribute: { [Function: memoized] cache: MapCache { size: 0, __data__: [Object] } } }

CONSOLE OUTPUT:
TypeError: undefined is not a function
    at createCarrot (/home/myhomedir/Projects/market-rewrite/api/controllers/carrotController.js:32:16)
    at Layer.handle [as handle_request] (/home/myhomedir/Projects/market-rewrite/api/node_modules/express/lib/router/layer.js:95:5)
    at next (/home/myhomedir/Projects/market-rewrite/api/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/home/myhomedir/Projects/market-rewrite/api/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/home/myhomedir/Projects/market-rewrite/api/node_modules/express/lib/router/layer.js:95:5)
    at /home/myhomedir/Projects/market-rewrite/api/node_modules/express/lib/router/index.js:281:22
    at Function.process_params (/home/myhomedir/Projects/market-rewrite/api/node_modules/express/lib/router/index.js:335:12)
    at next (/home/myhomedir/Projects/market-rewrite/api/node_modules/express/lib/router/index.js:275:10)
    at Function.handle (/home/myhomedir/Projects/market-rewrite/api/node_modules/express/lib/router/index.js:174:3)
    at router (/home/myhomedir/Projects/market-rewrite/api/node_modules/express/lib/router/index.js:47:12)
    at Layer.handle [as handle_request] (/home/myhomedir/Projects/market-rewrite/api/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/home/myhomedir/Projects/market-rewrite/api/node_modules/express/lib/router/index.js:317:13)
    at /home/myhomedir/Projects/market-rewrite/api/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/home/myhomedir/Projects/market-rewrite/api/node_modules/express/lib/router/index.js:335:12)
    at next (/home/myhomedir/Projects/market-rewrite/api/node_modules/express/lib/router/index.js:275:10)
    at /home/myhomedir/Projects/market-rewrite/api/node_modules/express/lib/router/index.js:635:15
    at next (/home/myhomedir/Projects/market-rewrite/api/node_modules/express/lib/router/index.js:260:14)
    at Function.handle (/home/myhomedir/Projects/market-rewrite/api/node_modules/express/lib/router/index.js:174:3)
    at router (/home/myhomedir/Projects/market-rewrite/api/node_modules/express/lib/router/index.js:47:12)
    at Layer.handle [as handle_request] (/home/myhomedir/Projects/market-rewrite/api/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/home/myhomedir/Projects/market-rewrite/api/node_modules/express/lib/router/index.js:317:13)
    at /home/myhomedir/Projects/market-rewrite/api/node_modules/express/lib/router/index.js:284:7

向相关路由发送 POST 请求会按预期调用控制器,但整个过程失败并出现 undefined is not a function 错误。

我一辈子都无法弄清楚这里到底出了什么问题。 console.log() 和 Chrome 的检查器都验证了一个模型确实正在被传入,但似乎是 .create()。 .build() 和 .save() 似乎也不存在。显然我错过了一些重要的事情,因为我看不出我的代码有什么问题。

当我把所有东西都塞进一个文件时,整个事情就起作用了,但是谁愿意这样做呢?

Using:
Node.js v8.10.0
Express 4.16.3
Sequelize 4.37.5

文件夹结构:

├── app.js
├── controllers
│   ├── associateController.js
│   ├── bookController.js
│   ├── carrotController.js
│   ├── categoryController.js
│   ├── colorController.js
│   └── genericModelActions.js
├── isolatedSequelizeTest.js
├── models
│   ├── associate.js
│   ├── book.js
│   ├── carrot.js
│   ├── category.js
│   ├── color.js
│   └── db.js
├── package.json
├── package-lock.json
├── public
│   └── stylesheets
│       └── style.css
├── routes
│   ├── bookRoutes.js
│   ├── carrotRoutes.js
│   ├── categoryRoutes.js
│   └── users.js
├── spec
│   ├── carrotRoutes.spec.js
│   └── support
│       └── jasmine.json
└── tempstorage.db

【问题讨论】:

  • 请您也发布文件夹结构吗?
  • @VivekDoshi 我按要求发布了文件结构。

标签: node.js express sequelize.js


【解决方案1】:

我认为你需要改变的是:

return model.create(...data);

return model.create(data);
// OR
return model.create({...data});

【讨论】:

  • 做到了。这个错误已经困扰我好几天了,所以我很感激你的帮助。非常感谢。
  • @cornjuliox ,它发生了一段时间 :) ,很高兴知道它有帮助,快乐编码顺便说一句:D
猜你喜欢
  • 2018-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多