Файловая структура проекта 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".*



мысли?

577   5  

5 ответов:

вот пример 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');

несколько ответов здесь действительно помогли мне разработать альтернативный подход. Первоначальный вопрос касается взлома просто определение схемы отсутствует, но я предпочитаю связывать определения схемы и модели в одном файле.

это в основном идея Питера, только экспорт определения модели путем переопределения модуля.экспорт, чтобы сделать доступ к модели с вашего контроллера немного менее подробным:

макет:
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.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

модели индекса/.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

    Ничего не найдено.