Виклик потрібно на мангуст моделі більше одного разу

У мене є моделі в мангусі, визначені таким чином:

user.js

module.exports = function() {
  var mongoose = require('mongoose');

 //Creates a new Mongoose Schema object
  var Schema = mongoose.Schema; 

 //Collection to hold users
  var UserSchema = new Schema({
      username: { type: String, required: true },
      password: { type: String, required: true },
    },{ 
      versionKey: false 
    }
  );

 //Creates the Model for the User Schema
  var User = mongoose.model('User', UserSchema);

  var getUserById = function(id, callback) {
    User.findById(id, callback);
  }

  var getUserByUsername = function(username, callback) {
    var query = {username: username};
    User.findOne(query, callback);
  }


  return {
    getUserById: getUserById,
    getUserByUsername: getUserByUsername
  }
}()

В основному я повертаю публічний інтерфейс, який можуть використовувати клієнти моделі користувача. I.E. мої маршрути для користувачів захоплюють модель і можуть викликати два загальноприйняті методи і нічого більше. Я роблю це, щоб зняти факт, що я використовую mongodb/mongoose з моїх маршрутів. Я, швидше за все, маю модель користувача, яка переговорить з postgres також в певний момент, або може просто перейти до postgres. Як такий, я не хочу переглядати код для місць в маршрутах, які називають мангустськими конкретними функціями.

Ось моя проблема. Найчастіше в коді, коли мені потрібен модуль, який я називаю

var someUtil = require('./someUtil');

Однак якщо я роблю це більш ніж один раз для моделі мангуста, я отримую помилку про те, що вона не може бути визначена двічі.

var User = require('./user'); //Cannot put this in more than one file without getting an error.

Чи є кращий спосіб кодувати файл user.js таким чином, що я можу надати публічний інтерфейс моїй моделі користувача, але тільки один раз визначити схему, щоб я міг зателефонувати більше одного разу на цей файл?

1
Вузол AFAIK кешує результат необхідності модуля, і, таким чином, вищезазначена функція не повинна виконуватися двічі. За винятком того, що немає причин переносити код у функцію самовиконання, просто відкрийте такі методи, як exports.getUserById = getUserById;//etc .
додано Автор Andreas Hultgren, джерело
Вузол AFAIK кешує результат необхідності модуля, і, таким чином, вищезазначена функція не повинна виконуватися двічі. За винятком того, що немає причин переносити код у функцію самовиконання, просто відкрийте такі методи, як exports.getUserById = getUserById;//etc .
додано Автор Andreas Hultgren, джерело

9 Відповіді

Ви повинні відокремити модель Mongoose від сервісу, з яким ви обертаєте його.

Я пропоную вам папку з моделями з 1 файлом на схему, кожен файл буде виглядати приблизно так:

'use strict';

var mongoose = require('mongoose'),
    Schema = mongoose.Schema

var User = new Schema({
    ...fields your schema will have
})

//additional virtuals or configuration

module.exports = mongoose.model('User', User)

потім мати папку services з сервісом UserService, що вимагає такої моделі:

var User = require('../models/User')

function UserService(){
    //create User, delete User, etc.
}

module.exports = new UserService()

тоді відтепер у ваші контролери або маршрути просто потрібно UserService. Ви не будете мати таких проблем і ваш код буде краще організований.

3
додано

Ви повинні відокремити модель Mongoose від сервісу, з яким ви обертаєте його.

Я пропоную вам папку з моделями з 1 файлом на схему, кожен файл буде виглядати приблизно так:

'use strict';

var mongoose = require('mongoose'),
    Schema = mongoose.Schema

var User = new Schema({
    ...fields your schema will have
})

//additional virtuals or configuration

module.exports = mongoose.model('User', User)

потім мати папку services з сервісом UserService, що вимагає такої моделі:

var User = require('../models/User')

function UserService(){
    //create User, delete User, etc.
}

module.exports = new UserService()

тоді відтепер у ваші контролери або маршрути просто потрібно UserService. Ви не будете мати таких проблем і ваш код буде краще організований.

3
додано

Андреас правильний:

AFAIK node caches the result of requireing a module, and thus the above function should not be run twice. Other than that there's no reason to wrap you code in a self-executing function, just expose the methods like exports.getUserById = getUserById; //etc.
0
додано

Андреас правильний:

AFAIK node caches the result of requireing a module, and thus the above function should not be run twice. Other than that there's no reason to wrap you code in a self-executing function, just expose the methods like exports.getUserById = getUserById; //etc.
0
додано

Я зіткнувся з цією проблемою, і я думав, що я внесу свою відповідь. Питання, яке я маю, трохи складніше, тому що в моїх схемах є "ref" визначення. Я не зовсім потрапив в нижню частину "чому", але в основному те, що відбувається, так чи інакше, ланцюжок залежностей викликає вузол, який вимагає одного файлу двічі. Це перевірено, оскільки я двічі отримую вивід console.log. Мій попередній підхід полягав у тому, щоб просто експортувати схеми замість моделей, але це дратувало, тому що мені довелося завантажувати всі моделі на початку виконання. Після деякого майстрування я зупинився на цій парадигмі (використовуючи coffeescript):

Mongoose = require 'mongoose'

unless 'Foo' in Mongoose.modelNames()
  schema = new Mongoose.Schema
    bar: String
  Mongoose.model 'Foo', schema

module.exports = Mongoose.model 'Foo'
0
додано

Я зіткнувся з цією проблемою, і я думав, що я внесу свою відповідь. Питання, яке я маю, трохи складніше, тому що в моїх схемах є "ref" визначення. Я не зовсім потрапив в нижню частину "чому", але в основному те, що відбувається, так чи інакше, ланцюжок залежностей викликає вузол, який вимагає одного файлу двічі. Це перевірено, оскільки я двічі отримую вивід console.log. Мій попередній підхід полягав у тому, щоб просто експортувати схеми замість моделей, але це дратувало, тому що мені довелося завантажувати всі моделі на початку виконання. Після деякого майстрування я зупинився на цій парадигмі (використовуючи coffeescript):

Mongoose = require 'mongoose'

unless 'Foo' in Mongoose.modelNames()
  schema = new Mongoose.Schema
    bar: String
  Mongoose.model 'Foo', schema

module.exports = Mongoose.model 'Foo'
0
додано

Я зіткнувся з цією проблемою, і я думав, що я внесу свою відповідь. Питання, яке я маю, трохи складніше, тому що в моїх схемах є "ref" визначення. Я не зовсім потрапив в нижню частину "чому", але в основному те, що відбувається, так чи інакше, ланцюжок залежностей викликає вузол, який вимагає одного файлу двічі. Це перевірено, оскільки я двічі отримую вивід console.log. Мій попередній підхід полягав у тому, щоб просто експортувати схеми замість моделей, але це дратувало, тому що мені довелося завантажувати всі моделі на початку виконання. Після деякого майстрування я зупинився на цій парадигмі (використовуючи coffeescript):

Mongoose = require 'mongoose'

unless 'Foo' in Mongoose.modelNames()
  schema = new Mongoose.Schema
    bar: String
  Mongoose.model 'Foo', schema

module.exports = Mongoose.model 'Foo'
0
додано

Я також зіткнувся з цією проблемою.

Щось ви можете зробити, це обернути визначення схеми в спробі уловити

Замініть цей рядок var User = mongoose.model ('Користувач', UserSchema); :

var User;
try {
  User = mongoose.model('User', UserSchema);
}
catch(e) {
  User = mongoose.model('User');
}

Не впевнений, що це найкращий спосіб, але він буде працювати.

0
додано

Я також зіткнувся з цією проблемою.

Щось ви можете зробити, це обернути визначення схеми в спробі уловити

Замініть цей рядок var User = mongoose.model ('Користувач', UserSchema); :

var User;
try {
  User = mongoose.model('User', UserSchema);
}
catch(e) {
  User = mongoose.model('User');
}

Не впевнений, що це найкращий спосіб, але він буде працювати.

0
додано
dev-ua/node
dev-ua/node
1 122 учасників

Chat for Node.js developers. We love other non-frontend JS environments too!