MissingSchemaError:尚未为模型“用户”注册架构
Posted
技术标签:
【中文标题】MissingSchemaError:尚未为模型“用户”注册架构【英文标题】:MissingSchemaError: Schema hasn't been registered for model "User" 【发布时间】:2014-01-16 21:37:30 【问题描述】:在我的models/user.js
文件中:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userSchema = new Schema(
(define schema)
);
...
(save user)
...
(check password)
...
mongoose.model('User', userSchema);
在我的router/index.js
中,我有:
var mongoose = require('mongoose');
var User = mongoose.model('User');
引发错误:
MissingSchemaError: Schema hasn't been registered for model "User".
但是,如果在user.js
中,我会这样做(在最后一行)
module.exports = mongoose.model('User', userSchema);
在index.js
我做var User = require('../models/User');
,然后一切正常。
但它不应该,因为在config/pass.js
我正在做var User = mongoose.model('User');
并且它完美地工作。
require('../models/User');
语法在 Ubuntu 上不起作用,但在我的 Mac 上。
我该怎么办?我如何解决它?我查看了大量示例应用程序,包括 MEAN,但没有任何帮助。
【问题讨论】:
我遇到了类似的问题,虽然@verybadalloc 的回答很有帮助,但我想看看我是否可以用另一种方式解决它。然后,当我撤消更改时,它仍然有效。所以,现在我仍然很困惑,但你的问题和答案有所帮助。我尝试将导出更改为也导出架构,这似乎有所帮助,但现在我不完全确定什么有效,因为撤消更改似乎没有任何影响。 【参考方案1】:我在尝试 MEAN 教程时遇到了同样的问题。
经过一番研究,我发现在 app.js 中,如果我将 require("./models/User") 放在 var routes = require("./routes/index") 之前,那么它可以工作。
像这样:
mongoose.connect("mongodb://localhost/news");
require("./models/Posts");
require("./models/Comments");
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
希望答案会有所帮助!
【讨论】:
好人,做同样的教程,这个答案为我节省了很多时间 确实有助于在路线之前添加模型 异步行为很强大,但正确使用也有点困难。感谢您的回答!【参考方案2】:发生错误是因为在加载 router/index.js
时尚未解释 models/user.js
。解决此问题的一种方法是执行以下操作:
var mongoose = require('mongoose');
//Load all your models
var User = require('./../models/user.js');
//Now, this call won't fail because User has been added as a schema.
mongoose.model('User');
然而,事实证明这违反了最佳实践,这表明所有这些配置内容都应该发生在您的 app.js
文件的开头。从madhums' example project看这个例子
var models_path = __dirname + '/app/models'
fs.readdirSync(models_path).forEach(function (file)
if (~file.indexOf('.js')) require(models_path + '/' + file)
)
请注意,他是在设置应用程序的路由器之前加载他的模型。
至于 Ubuntu 与 Mac 的问题,我相信这是因为 Ubuntu 中的相对路径必须以 ./
开头。您只需将其更改为 ./../models/user.js
,它适用于 Mac。
【讨论】:
该代码应该放在哪里?令我惊讶的是,删除./
在两个系统中都有效,但 ./
在 Ubuntu 上无效。
在您配置/启动快速服务器的文件中 - 在您的路线文件加载之前。【参考方案3】:
猫鼬模式 js 文件中的所有代码都应该在用于其他文件之前运行。
例如,以下代码 sn-p 确保执行 mongoose 架构文件/模块。
fs.readdirSync(__dirname + '/app/models').forEach(function (file) if (~file.indexOf('.js')) require(__dirname + '/app/models/' + file); );
或者架构文件可以通过调用手动执行
var User = require('./app/models/user.js')
在模型用于应用程序中的任何位置之前。
完成上述操作后,可以要求/执行其他使用猫鼬模型的模块。
【讨论】:
【参考方案4】:我确实研究了很多,我找到了一个解决方案,所以我把这个解决方案分享给你,没有人可以面对我犯的那个小错误。
请记住,您只需在 ref
中添加与您在 model
中提供的名称相同的名称,因为它区分大小写( Product !== product )。
const Product = new mongoose.model('Product', productSchema);
product:
type: mongoose.Schema.ObjectId,
ref: 'Product', <-- Should be same as modelName
required: [true, 'Cart must belong to a product']
【讨论】:
【参考方案5】:在加载模型文件加载之前尝试获取模型时出现此问题
我在 mean.io 项目中解决了同样的问题
在控制器中:
'use strict';
require('../models/settingsModel'); // load settingsModel.js file before get mongoose.model('Settings')
var mongoose = require('mongoose'),
Settings = mongoose.model('Settings'),
Q = require('q');
【讨论】:
【参考方案6】:就我而言,这是由于大写/小写字母混淆而发生的。 用户模型有这个:
const userSchema = new Schema(
// ...
);
module.exports = mongoose.model('User', userSchema);
并且 Product 模型引用了 User 模型,但小案例:
const productSchema = new Schema(
// ...
userId:
type: Schema.Types.ObjectId,
ref: 'user', // This should exactly match the name of User model above!!!
required: true
);
【讨论】:
我很感激...我在模式关联参考中使用了gearItem
...但是模型本身被命名为GearItem
...哎呀?感谢您提供这个额外的答案!跨度>
救了我。虽然我之前在其他项目中这样做过,但我错过了这个花了 3 个小时才弄清楚的小部分。【参考方案7】:
我在使用 ES6/Typescript 时也遇到过这个错误。即使我导入了模型,错误仍然存在。根据文档here
MongooseError.MissingSchemaError
当您尝试访问尚未注册的模型时抛出
import model, Schema from 'mongoose';
import Company from './CompanyModel';
const ProjectSchema = new Schema(
company: type: Schema.Types.ObjectId, ref: "Company"
);
export default model('Project', ProjectSchema);
提示只是为了确保明确使用模型,因此将 ref:"Company"
更改为 ref:Company.modelName
似乎解决了问题。
希望对大家有所帮助
【讨论】:
【参考方案8】: 您需要在代码中要求您的模型 在您调用 mongoose.model 之前,Mongoose 不会识别您已定义模型,并且只有在您需要模型时才会调用它例如。
在下面的例子中,如果你不做const Role = require("./role");
,你会得到MissingSchemaError: Schema hasn't been registered for model “Role”
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const Role = require("./role");
const userSchema = new Schema(
role: type: Schema.Types.ObjectId, ref: "Role", required: false ,
username: type: String, required: true, trim: true ,
password: type: String, required: true, trim: true ,
email: type: String, required: true, trim: true
,
timestamps: true
);
module.exports = mongoose.model("User", userSchema);
【讨论】:
【参考方案9】:在使用 express 时,一个常见的错误是在 mongoose 之前要求 express。这将导致“MissingSchemaError:尚未为模型“用户”注册模式。”错误。
您可以通过更正“要求”顺序(即猫鼬然后快递)轻松修复它
var mongoose = require('./config/mongoose'),
express = require('./config/express');
【讨论】:
就是这样...这是最简单的解决方案。谢谢@bwaaaaaa【参考方案10】:我在尝试使用 mongoose-fixture
将一些默认数据播种到 mongo 集合中时遇到此错误。困惑了很长时间,跟随这个和类似的线程寻求帮助,试图调试。最终,在我的情况下,问题出在mongoose
和mongoose-fixture
版本。
如果没有代码更改帮助,或者如果您在尝试正确使用 mongoose-fixture
(它应该为您注册您的模式)时遇到此错误,请尝试此操作。删除项目的node_modules
目录,运行npm cache clean
,然后运行npm install
。
如果即使这样也没有帮助,请尝试比较有问题的应用程序和有效应用程序之间的mongoose
/ mongoose-fixture
版本,并尝试更改package.json
中的版本,然后重复上述步骤。这对我有用。
【讨论】:
【参考方案11】:我最近遇到了一个类似于 @rajkumar-nagarajan 和 @verybadalloc 提供的答案的解决方案。
我更喜欢这种方法,因为它避免了 n+1 次迭代,并且不会从文件系统中读取所有模型。
在app/models/index.js
,需要每个模型文件:
require('./model1');
require('./model2');
require('./model3');
然后,在/app.js
或/index.js
(无论您的项目使用哪个),您现在可以简单地执行以下操作:
require('./app/models');
我缺少的部分(此处赞赏任何提示)--如何按名称轻松注册每个模型,例如:
mongoose.model('Model1')
【讨论】:
【参考方案12】:我犯了一个不同的错误,就像我创建了架构一样,但问题是我没有使用架构模型(用于插入、更新、读取和删除文档)。
即我创建了类似的集合:
const playerSchema = new Schema(
bowling:
style: String,
arm: String,
)
export const PlayerSchema = model('Player', playerSchema)
但没有在某处使用或调用 PlayerSchema
模型,这就是我收到此错误的原因。
【讨论】:
我想你的意思是你没有使用或打电话给playerSchema
(不是PlayerSchema
)。【参考方案13】:
我在尝试在本教程User Auth on MEAN stack 的基础代码上添加新模型时遇到了这个问题。解决方案就像Ahei 提到的那样。
具体来说,我需要在/app_api/models/db.js
的末尾添加一行require('path/to/your/model')
,这在app.js
中是必需的。为了便于开发,最好保持结构的一致性。
【讨论】:
【参考方案14】:我尝试了上述所有解决方案,但都失败了,我发现解决方案是清除我的数据库(MongoDB),然后重新运行应用程序
【讨论】:
【参考方案15】:问题出现在模型的require()
语句中。您需要像这样将所有 MongoDB 依赖项移动到路由依赖项之上,例如
//blog.js file
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const blogSchema = new Schema(
title : String
);
mongoose.model('blogs', blogSchema);
在 server.js 中
//server.js file
require('dotenv').config();
const mongoose = require('mongoose');
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
require('./models/blog');
const Blog = mongoose.model('blogs');
const URL = process.env.MONGO_DB_URL;
mongoose.connect(URL,
useNewUrlParser: true,
useUnifiedTopology: true,
);
mongoose.connection
.once('open', () => console.log('Connected to MongoLab instance.'))
.on('error', (error) => console.log('Error connecting to MongoLab:', error));
const app = express();
app.use(cors());
app.use(bodyParser.urlencoded( extended: false ));
app.use(bodyParser.json());
app.get('/', (req,res)=>
res.send('Hello World')
);
app.post('/blog',async (req, res) =>
const blog = await new Blog(req.body).save();
res.send('just an example');
);
【讨论】:
【参考方案16】:如果您因架构中的 ref
字段而面临此错误,您需要提供用于该建模参考架构的确切名称(区分大小写)。
// models/User.js
const userSchema = new Schema( name: String );
module.exports = mongoose.model('User', userSchema); // note the 1st arg
// models/Post.js
const postSchema = new Schema(
user:
type: mongoose.Schema.Types.ObjectId,
ref: 'User' // `ref` must be 'User' not 'user'
,
)
module.exports = mongoose.model('Post', postSchema)
还有
在查询时调用.populate()
时,必须在调用参考模型之前对其进行建模。
这是因为models/User.js
不会在此处的其他任何地方执行,因此通过导入您将使User
在mongoose.models
对象中可用。
在实际项目中,User
模型文件在整个项目中至少导入一次,因此请确保您至少导入了一次参考模型。
// your app
const User = require('./models/User') // important to import
const Post = require('./models/Post')
//console.log(!!mongoose.models.User) // true
//..
const post = await Post.findOne().populate( path : 'user' )
另一种方法是在Post
模型中导入User
模型并将其用于ref
字段。
// models/User.js
const userSchema = new Schema( name: String );
module.exports = mongoose.model('User', userSchema);
// models/Post.js
const User = require('./User')
const postSchema = new Schema(
user:
type: mongoose.Schema.Types.ObjectId,
ref: User, // here we are directly referring model instance itself instead of model name.
);
module.exports = mongoose.model('Post', postSchema)
& 当然有很多方法可以解决这个问题。
【讨论】:
【参考方案17】:如果您使用的是 Mean.js 堆栈,请使用以下命令运行测试:
grunt test
而不是
mocha
【讨论】:
这与测试无关。以上是关于MissingSchemaError:尚未为模型“用户”注册架构的主要内容,如果未能解决你的问题,请参考以下文章
Passport.js 抛出错误,MissingSchemaError(name)
使用 mongoose-observer 库时出现 MissingSchemaError