Файловая структура проекта Mongoose & NodeJS
В настоящее время у меня есть все мои модели (определения схемы) в /models/models.js-файл для моего приложения Mongoose/NodeJS.
Я хотел бы разбить их на разные файлы как таковые: user_account.Яш, профиль.js, etc. Однако я не могу этого сделать, так как мои контроллеры ломаются и отчитываются "не удается найти модуль" как только я разделю эти классы.
моя структура проекта выглядит следующим образом:
/MyProject
/controllers
user.js
foo.js
bar.js
// ... etc, etc
/models
models.js
server.js
содержание моих моделей.файл 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 }
});
мой пользователь.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".*
мысли?
5 ответов:
вот пример
app/models/item.jsvar 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');
несколько ответов здесь действительно помогли мне разработать альтернативный подход. Первоначальный вопрос касается взлома просто определение схемы отсутствует, но я предпочитаю связывать определения схемы и модели в одном файле.
это в основном идея Питера, только экспорт определения модели путем переопределения модуля.экспорт, чтобы сделать доступ к модели с вашего контроллера немного менее подробным:
макет:MyProject /controllers user.js foo.js bar.js // ... etc, etc /models Item.js server.jsмодели/деталя.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и вы получаете доступ к модели в контроллере, скажем пользователей.js, например:
var Item = require(__dirname+'/../models/Item') ... var item = new Item({name:'Foobar'});не забудьте позвонить мангуста.связываться.(.) в серверах.js, или где еще вы считаете уместным!
недавно я ответил на вопрос Quora относительно этой же проблемы. http://qr.ae/RoCld1
то, что я нашел очень приятно и экономит на количестве требуются вызовы-это структурирование ваших моделей в один каталог. Убедитесь, что у вас есть только одна модель для каждого файла.
создать индекс.js-файл в том же каталоге, что и ваши модели. Добавьте к нему этот код. Будьте уверены, чтобы добавить необходимые fs требуйте
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.jsnote: 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.jsvar mongoose = require('mongoose'); var Item = mongoose.model('Item', require('../models/item'));другой способ без
module.exportsилиrequire:
app/models/item.jsvar mongoose = require("mongoose"); var ItemSchema = new mongoose.Schema({ name: { type: String, index: true }, ... }); mongoose.model('Item', ItemSchema); // register modelна
app/controllers/items.jsvar mongoose = require('mongoose') , Item = mongoose.model('Item'); // registered model
вдохновленный sequelize-cli, у меня есть каталог моделей, где я определяю все схемы.
полное приложение на github:https://github.com/varunon9/node-starter-app-mongo
модели индекса/.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;модели/пользователя.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: { } };
Comments