当使用bookshelf的时候,得到“不能读取属性'toString'的undefined”

我有一套看起来像这样的Bookshelf模型:

const User = bookshelf.Model.extend({ tableName: 'users', hasTimestamps: true, posts: function() { return this.hasMany(Posts); }, }); const Posts = bookshelf.Model.extend({ tableName: 'posts', hasTimestamps: true, author: function() { return this.belongsTo(User); }, }); 

使用knex,我像这样设置模式:

 Promise.all([ knex.schema.createTableIfNotExists('users', (tbl) => { tbl.increments('id').primary(); tbl.string('name'); tbl.string('username'); tbl.string('email'); tbl.timestamps(); }), knex.schema.createTableIfNotExists('posts', (tbl) => { tbl.increments(); tbl.string('title'); tbl.string('body'); tbl.integer('author').references('users.id'); tbl.timestamps(); }) ]); 

当我然后运行下面的服务器路线devise来获取一个职位:

 app.get('/post/:id', (req,res) => { if(_.isUndefined(req.params.id)) return; Posts .forge({id: req.params.id}) .fetch({withRelated: 'author'}) .then((post) => { res.send(post); }); }); 

我得到以下错误:

 Unhandled rejection TypeError: Cannot read property 'toString' of undefined at Object.prepareValue (/Users/ethan/Flatiron/node/unit4/node-js-intro-to-bookshelf/node_modules/knex/lib/dialects/postgres/utils.js:48:13) at /Users/ethan/Flatiron/node/unit4/node-js-intro-to-bookshelf/node_modules/knex/lib/dialects/postgres/index.js:61:20 at arrayMap (/Users/ethan/Flatiron/node/unit4/node-js-intro-to-bookshelf/node_modules/knex/node_modules/lodash/lodash.js:595:23) at map (/Users/ethan/Flatiron/node/unit4/node-js-intro-to-bookshelf/node_modules/knex/node_modules/lodash/lodash.js:8778:14) at Client.prepBindings (/Users/ethan/Flatiron/node/unit4/node-js-intro-to-bookshelf/node_modules/knex/lib/dialects/postgres/index.js:60:28) at QueryCompiler_PG.toSQL (/Users/ethan/Flatiron/node/unit4/node-js-intro-to-bookshelf/node_modules/knex/lib/query/compiler.js:49:37) at QueryBuilder.toSQL (/Users/ethan/Flatiron/node/unit4/node-js-intro-to-bookshelf/node_modules/knex/lib/query/builder.js:40:44) at /Users/ethan/Flatiron/node/unit4/node-js-intro-to-bookshelf/node_modules/knex/lib/runner.js:34:32 at tryCatcher (/Users/ethan/Flatiron/node/unit4/node-js-intro-to-bookshelf/node_modules/knex/node_modules/bluebird/js/release/util.js:16:23) at /Users/ethan/Flatiron/node/unit4/node-js-intro-to-bookshelf/node_modules/knex/node_modules/bluebird/js/release/using.js:184:26 at tryCatcher (/Users/ethan/Flatiron/node/unit4/node-js-intro-to-bookshelf/node_modules/knex/node_modules/bluebird/js/release/util.js:16:23) at Promise._settlePromiseFromHandler (/Users/ethan/Flatiron/node/unit4/node-js-intro-to-bookshelf/node_modules/knex/node_modules/bluebird/js/release/promise.js:502:31) at Promise._settlePromise (/Users/ethan/Flatiron/node/unit4/node-js-intro-to-bookshelf/node_modules/knex/node_modules/bluebird/js/release/promise.js:559:18) at Promise._settlePromise0 (/Users/ethan/Flatiron/node/unit4/node-js-intro-to-bookshelf/node_modules/knex/node_modules/bluebird/js/release/promise.js:604:10) at Promise._settlePromises (/Users/ethan/Flatiron/node/unit4/node-js-intro-to-bookshelf/node_modules/knex/node_modules/bluebird/js/release/promise.js:683:18) at Promise._fulfill (/Users/ethan/Flatiron/node/unit4/node-js-intro-to-bookshelf/node_modules/knex/node_modules/bluebird/js/release/promise.js:628:18) at PromiseArray._resolve (/Users/ethan/Flatiron/node/unit4/node-js-intro-to-bookshelf/node_modules/knex/node_modules/bluebird/js/release/promise_array.js:125:19) at PromiseArray._promiseFulfilled (/Users/ethan/Flatiron/node/unit4/node-js-intro-to-bookshelf/node_modules/knex/node_modules/bluebird/js/release/promise_array.js:143:14) at Promise._settlePromise (/Users/ethan/Flatiron/node/unit4/node-js-intro-to-bookshelf/node_modules/knex/node_modules/bluebird/js/release/promise.js:564:26) at Promise._settlePromise0 (/Users/ethan/Flatiron/node/unit4/node-js-intro-to-bookshelf/node_modules/knex/node_modules/bluebird/js/release/promise.js:604:10) at Promise._settlePromises (/Users/ethan/Flatiron/node/unit4/node-js-intro-to-bookshelf/node_modules/knex/node_modules/bluebird/js/release/promise.js:683:18) at Async._drainQueue (/Users/ethan/Flatiron/node/unit4/node-js-intro-to-bookshelf/node_modules/knex/node_modules/bluebird/js/release/async.js:138:16) at Async._drainQueues (/Users/ethan/Flatiron/node/unit4/node-js-intro-to-bookshelf/node_modules/knex/node_modules/bluebird/js/release/async.js:148:10) at Immediate.Async.drainQueues [as _onImmediate] (/Users/ethan/Flatiron/node/unit4/node-js-intro-to-bookshelf/node_modules/knex/node_modules/bluebird/js/release/async.js:17:14) at tryOnImmediate (timers.js:534:15) at processImmediate [as _immediateCallback] (timers.js:514:5) 

有人知道这里发生了什么?

您正在使用非标准外键名称( author而不是author_id – 请参阅http://bookshelfjs.org/#Model-instance-belongsTo )。 所以你的模型的关系应该被固定为:

 const User = bookshelf.Model.extend({ tableName: 'users', hasTimestamps: true, posts: function() { return this.hasMany(Posts, 'author'); }, }); const Posts = bookshelf.Model.extend({ tableName: 'posts', hasTimestamps: true, author: function() { return this.belongsTo(User, 'author'); }, });