現在、Mongoose/NodeJSアプリケーションの/models/models.jsファイルにすべてのモデル(スキーマ定義)があります。
User_account.js、profile.jsなど、これらを別のファイルに分割したいと思います。ただし、コントローラーが壊れて「モジュールが見つかりません」と報告するため、そうは思えません。これらのクラスを分解すると.
私のプロジェクト構造は次のとおりです。
/MyProject
/controllers
user.js
foo.js
bar.js
// ... etc, etc
/models
models.js
server.js
Models.jsファイルの内容は次のようになります。
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
ObjectId = Schema.ObjectId;
mongoose.connect('mongodb://localhost/mydb');
var UserAccount = new Schema({
user_name : { type: String, required: true, lowercase: true, trim: true, index: { unique: true } },
password : { type: String, required: true },
date_created : { type: Date, required: true, default: Date.now }
});
var Product = new Schema({
upc : { type: String, required: true, index: { unique: true } },
description : { type: String, trim: true },
size_weight : { type: String, trim: true }
});
私のuser.jsファイル(コントローラ)は次のようになります:
var mongoose = require('mongoose'),
UserAccount = mongoose.model('user_account', UserAccount);
exports.create = function(req, res, next) {
var username = req.body.username;
var password = req.body.password;
// Do epic sh...what?! :)
}
スキーマ定義を複数のファイルに分割し、コントローラーから参照するにはどうすればよいですか? (スキーマが新しいファイルになった後)参照すると、次のエラーが表示されます。
*エラー:モデル "user_account"のスキーマが登録されていません。*
考え?
サンプルapp/models/item.js
は次のとおりです
var mongoose = require("mongoose");
var ItemSchema = new mongoose.Schema({
name: {
type: String,
index: true
},
equipped: Boolean,
owner_id: {
type: mongoose.Schema.Types.ObjectId,
index: true
},
room_id: {
type: mongoose.Schema.Types.ObjectId,
index: true
}
});
var Item = mongoose.model('Item', ItemSchema);
module.exports = {
Item: Item
}
これをapp/controllers/items.js
のアイテムコントローラーからロードするには
var Item = require("../models/item").Item;
//Now you can do Item.find, Item.update, etc
つまり、モデルモジュールでスキーマとモデルの両方を定義し、モデルのみをエクスポートします。相対要求パスを使用して、モデルモジュールをコントローラーモジュールに読み込みます。
接続を確立するには、サーバー起動コード(server.js
など)の早い段階で処理します。通常、構成ファイルまたは環境変数のいずれかから接続パラメーターを読み取り、構成が提供されない場合はデフォルトで開発モードlocalhostを使用します。
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost');
ここでのいくつかの回答は、私が代替アプローチを開発するのに本当に役立ちました。元の質問は、justスキーマ定義の破壊に関するものですが、スキーマとモデルの定義を同じファイルにバンドルすることを好みます。
これはほとんどPeterのアイデアであり、module.exportsをオーバーライドしてモデル定義をエクスポートするだけで、コントローラーからモデルへのアクセスが少し冗長になります。
プロジェクトのレイアウト:
MyProject
/controllers
user.js
foo.js
bar.js
// ... etc, etc
/models
Item.js
server.js
models/Item.jsは次のようになります。
var mongoose = require("mongoose");
var ItemSchema = new mongoose.Schema({
name: {
type: String,
index: true
}
});
module.exports = mongoose.model('Item', ItemSchema);
// Now `require('Item.js')` will return a mongoose Model,
// without needing to do require('Item.js').Item
そして、コントローラのモデル、たとえばuser.jsにアクセスします:
var Item = require(__dirname+'/../models/Item')
...
var item = new Item({name:'Foobar'});
Server.jsでmongoose.connect(..)を呼び出すことを忘れないでください。他の適切な場所で呼び出すこともできます。
私は最近、この同じ問題に関するQuoraの質問に回答しました。 http://qr.ae/RoCld1
私が非常にすてきで、require呼び出しの量を節約できるのは、モデルを単一のディレクトリに構造化することです。ファイルごとにモデルが1つだけであることを確認してください。
モデルと同じディレクトリにindex.jsファイルを作成します。このコードを追加します。必ず必要なfsrequireを追加してください
var fs = require('fs');
/*
* initializes all models and sources them as .model-name
*/
fs.readdirSync(__dirname).forEach(function(file) {
if (file !== 'index.js') {
var moduleName = file.split('.')[0];
exports[moduleName] = require('./' + moduleName);
}
});
これで、すべてのモデルを次のように呼び出すことができます。
var models = require('./path/to/models');
var User = models.user;
var OtherModel = models['other-model'];
ピーター・ライオンズはその基盤をほとんどカバーしました。
上記の例からの借用(スキーマの後の行の削除)追加したいのは次のとおりです。
app/models/item.js
note: notice where `module.exports` is placed
var mongoose = require("mongoose");
var ItemSchema = module.exports = new mongoose.Schema({
name: {
type: String,
index: true
},
...
});
app/controllers/items.js
から読み込むには
var mongoose = require('mongoose');
var Item = mongoose.model('Item', require('../models/item'));
module.exports
またはrequire
を使用しない別の方法:
app/models/item.js
var mongoose = require("mongoose");
var ItemSchema = new mongoose.Schema({
name: {
type: String,
index: true
},
...
});
mongoose.model('Item', ItemSchema); // register model
app/controllers/items.js
var mongoose = require('mongoose')
, Item = mongoose.model('Item'); // registered model
Sequelize-cliに触発され、すべてのスキーマを定義するモデルディレクトリがあります。
Githubの完全なアプリ: https://github.com/varunon9/node-starter-app-mongo
models/index.js-
'use strict';
const fs = require('fs');
const path = require('path');
const mongoose = require('mongoose');//.set('debug', true);
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config.json')[env];
const db = {};
const Schema = mongoose.Schema;
fs
.readdirSync(__dirname)
.filter(fileName => {
return (
fileName.indexOf('.') !== 0)
&& (fileName !== basename)
&& (fileName.slice(-3) === '.js'
);
})
.forEach(fileName => {
const model = require(path.join(__dirname, fileName));
const modelSchema = new Schema(model.schema);
modelSchema.methods = model.methods;
modelSchema.statics = model.statics;
// user.js will be user now
fileName = fileName.split('.')[0];
db[fileName] = mongoose.model(fileName, modelSchema);
});
module.exports = db;
models/user.js-
'use strict';
module.exports = {
schema: {
email: {
type: String,
required: true,
unique: true,
},
mobile: {
type: String,
required: false
},
name: {
type: String,
required: false
},
gender: {
type: String,
required: false,
default: 'male'
},
password: {
type: String,
required: true
},
dob: {
type: Date,
required: false
},
deactivated: {
type: Boolean,
required: false,
default: false
},
type: {
type: String,
required: false
}
},
// instance methods goes here
methods: {
},
// statics methods goes here
statics: {
}
};