所以我有一个用express.js构建的小型REST API和sequelize我已经重构成几个文件,因为我想成为但在这个过程中我的模型的.create()方法似乎有“消失”了。 (我是JS btw的新手)
// 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
答案 0 :(得分:1)
我认为你需要改变的是:
return model.create(...data);
要
return model.create(data);
// OR
return model.create({...data});