【问题标题】:Mongoose subdocs: cannot call method call to of undefinedMongoose 子文档:无法调用未定义的方法调用
【发布时间】:2012-11-05 22:16:42
【问题描述】:
TypeError: Cannot call method 'call' of undefined
    at Array.MongooseArray._cast (/Users/bodo/Documents/Repositories/EnabreNode/node_modules/mongoose/lib/types/array.js:78:15)
    at Object.map (native)
    at Array.MongooseArray.push (/Users/bodo/Documents/Repositories/EnabreNode/node_modules/mongoose/lib/types/array.js:187:23)
    at module.exports (/Users/bodo/Documents/Repositories/EnabreNode/accounts/routes/me.js:29:27)
    at callbacks (/Users/bodo/Documents/Repositories/EnabreNode/node_modules/express/lib/router/index.js:160:37)
    at Promise.module.exports (/Users/bodo/Documents/Repositories/EnabreNode/middleware/load_user.js:15:13)
    at Promise.addBack (/Users/bodo/Documents/Repositories/EnabreNode/node_modules/mongoose/lib/promise.js:128:8)
    at Promise.EventEmitter.emit (events.js:96:17)
    at Promise.emit (/Users/bodo/Documents/Repositories/EnabreNode/node_modules/mongoose/lib/promise.js:66:38)
    at Promise.complete (/Users/bodo/Documents/Repositories/EnabreNode/node_modules/mongoose/lib/promise.js:77:20)

我其实想构建一个非常简单的架构:

{
    username: "bodo",
    email: "info@example.com",
    contacts: [{ 
        user: { username: "john", email: "john@google.com" }, 
        messages: [
            { 
                sender: { username: "bodo", email: "info@example.com" },
                receiver: { username: "john", email: "john@google.com" },
                body: "How are you these days?"
            },
            { 
                sender: { username: "john", email: "john@google.com" },                                       
                receiver: { username: "bodo", email: "info@example.com" },
                body: "I am totally fine?"
            } 
        ]
    }]
};

contacts 属性包含一个 contacts 子文档,它包含实际联系人的用户对象(作为参考)以及一些元数据,如 hasAcceptedContactRequest、contactSince 等。 此外,我还保存来自聊天的消息子文档。这些消息子文档包含消息作为正文属性以及谁发送或接收了它。发送方和接收方再次引用了可以填充的完整用户对象。

理论上讲了这么多。我现在已经创建了这些模式:

用户架构

var Mongoose = require('mongoose');
var ContactSchema = require('./contact');

var UserSchema = new Mongoose.Schema({

    username: { 
        type: String, 
        index: { unique: true, sparse: true }, 
        required: true, lowercase: true, trim: true
    },

    email: {
        type: String,
        index: { unique: true, sparse: true }, 
        required: true, lowercase: true, trim: true
    },

    contacts: [ContactSchema]

});

module.exports = Mongoose.model('User', UserSchema, 'Users');

ContactSchema

var Mongoose = require('mongoose');
var MessageSchema = require('./message');

var ContactSchema = new Mongoose.Schema({

    user: {
        ref: "User",
        type: Mongoose.Schema.Types.ObjectId
    },

    messages: [MessageSchema]

});

module.exports = ContactSchema;

消息架构

var MessageSchema = new Mongoose.Schema({

    body: {
        type: String
    },

    sender: {
        ref: "User",
        type: Mongoose.Schema.Types.ObjectId
    },

    receiver: {
        ref: "User",
        type: Mongoose.Schema.Types.ObjectId
    }

});

module.exports = ContactSchema;

那是路线

app.put('/me', loadUser, function(req, res, next) {
    var user = req.user;
    var body = req.body;

    if (body.contacts) {
        body.contacts.forEach(function(contact) {
            user.contacts.push({ user: contact });
        });
    }

    console.log(req.user);

    user.save(function(err, user) {
        if (err) return next(err);
        res.send(200);
    });
});

解决方案: 正如 johnyHK 提到的,使用 node 的模块系统存在问题。我一不小心 将模式导出为模型。您现在可以看到上面更正后的示例。所以他们应该工作。

【问题讨论】:

    标签: javascript mongodb reference mongoose document


    【解决方案1】:

    假设您的架构定义在您的代码中的顺序是相同的,您需要对它们重新排序,以便在使用时完全定义所引用的架构。

    那就是:

    1. MessageSchema
    2. ContactSchema
    3. UserSchema

    【讨论】:

    • 您好,如何订购?目前该路由需要 user.js 需要 contact.js 需要 message.js 还是你的意思是把它们放在一起?
    • 所以我将所有模式合并到一个文件中,然后看到它工作正常!所以你的想法是对的我会搜索如何控制模块顺序
    • 好吧抱歉,我没有发现任何关于该问题的有用信息。 Couly 你提供了一个例子,我怎么说 require() 等到模块被加载?
    • @kyogron 只要您按照您的描述将架构拆分为单独的文件,并且您的require 语句位于文件的顶部,那么这应该可以工作。 require 是同步的。
    • @kyogron 您顶部的示例文档与包含大量 ObjectId 引用的架构定义不匹配。您能否更新您的问题以显示您推送到user 文档的body.contacts 的内容?
    【解决方案2】:

    试试这个:

       user : { type: Schema.ObjectId, ref: 'User', index: true }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-09
      • 2013-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多