【问题标题】:Store models in folder, use index.js to require them all将模型存储在文件夹中,使用 index.js 全部要求
【发布时间】:2013-06-19 06:40:11
【问题描述】:

我有一个规模不错的项目,我需要进行一些重组。

我正在使用 mongoose 作为我的节点 ORM。我想把我所有的猫鼬模型放在一个名为“模型”的文件夹中。我已经读过,当我这样做时,我可以在模型文件夹中放置一个 index.js 文件,这样就可以拉入所有模型并存储它们。

app.js:

...
var mongoose = require('mongoose');
var models = require('./models')(mongoose);

app.configure(function () {
  mongoose.connect(dbPath, function(err) {
    if (err) throw err;
  });
  ...
});

// include models in my routes so I need access
...

我被困在 index.js 中返回我的所有模型需要做什么

index.js(这是我尝试过的,甚至没有关闭)

function Models(mongoose) {
    var Counters = require('./counters')(mongoose);
    var User = require('./user')(mongoose);
    var Token = require('./token')(mongoose);
    var Team = require('./team')(mongoose);
    var Role =  require('./role')();
    var Layer = require('./layer')(mongoose, counters);
    var Feature = require('./feature')(mongoose, counters, async);


}

module.exports = Models;

我还应该从 app.js 传入 mongoose,因为我需要在那里连接到 mongo? IE。我可以在 index.js 中再次要求它,但我不确定在不同的文件中要求相同的模块是否是不好的做法。

编辑:(这是我的模型)

抱歉,我在模型类中添加了“访问器”类型的函数。 IE。我想为每个模型提供一个公共接口。

user.js:

module.exports = function(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
  }
} 

【问题讨论】:

    标签: node.js commonjs


    【解决方案1】:

    在 node.js 中,模块在第一次加载后被缓存。所以你不需要从 app.js 传递mongoose

    例如在models/index.js中:

    require('./counters')
    exports.User = require('./user')
    require('./token');
    require('./team');
    require('./role');
    require('./layer');
    require('./feature');
    // I prefer to use a loop to require all the js files in the folder.
    

    在模型/user.js 中:

    var mongoose = require('mongoose');
    var userSchema = mongoose.Schema({
      // ... Define your schema here
    });
    
    var User = module.exports = mongoose.model('User', userSchema);
    module.exports.getUserById = function(id, callback) {
      User.findById(id, callback);
    }
    
    module.exports.getUserByUsername = function(username, callback) {
      var query = {username: username};
      User.findOne(query, callback);
    }
    

    在 app.js 中:

    var mongoose = require('mongoose');
    var models = require('./models');
    
    mongoose.connect(dbPath, function(err) {
      if (err) throw err;
    });
    
    // Yes! You can use the model defined in the models/user.js directly
    var UserModel = mongoose.model('User');
    
    // Or, you can use it this way:
    UserModel = models.User;
    
    app.get('/', function(req, res) {
      var user = new UserModel();
      user.name = 'bob';
      user.save();
      // UserModel.getUserByUsername();
      ...
    });
    

    详细了解 node.js 中的模块缓存: http://nodejs.org/api/modules.html#modules_caching

    【讨论】:

    • 感谢您的解释,这是有道理的。我添加了我的模型代码的另一件事。我喜欢它为我的用户模型提供了一个“公共”接口。要使用它,尽管我需要将模型保存在某个地方以便以后可以访问它,对吗?想象一下,我的 models/index.js 可以在 export.modules 中返回一些东西,这样我就可以访问我所有的自定义模型了吗?
    • @forumuser 我认为您应该改用静态构造函数方法。见mongoosejs.com/docs/guide.html(静态)
    • 我试图阻止用户使用 Mongoose 静态函数,以便从用户那里抽象出 Mongoose 的使用。 IE 不使用猫鼬静态构造函数,只使用我返回的公共 API。如果我从 mongodb 迁移到 postgres,这会更容易,因为我的所有路由仍然可以调用我定义的相同公共方法,我只需要更改方法的内容。
    • @luin 使用这个我得到OverwriteModelError: Cannot overwrite User model once compiled.
    【解决方案2】:

    另一种以简单干净的方式调用所有模型的非常好的方法可能是这个:

    项目结构:

    .   
    ├── app.js
    └── models
        ├── Role.js
        ├── Team.js
        └── User.js
    

    app.js

    const fs = require('fs');
    const path = require('path');
    
    const modelsPath = path.resolve(__dirname, 'models')
    fs.readdirSync(modelsPath).forEach(file => {
      require(modelsPath + '/' + file);
    })
    

    【讨论】:

    • 邪恶!从不加载动态模型。您将失去代码完成!见:itnext.io/…
    【解决方案3】:

    只需在 models 文件夹中创建 index.js 并在其中添加以下代码

    const fs = require("fs");
    
    fs.readdirSync(__dirname).forEach((file) => {
      require("./" + file);
    });
    

    现在只需 require("./models"); 文件夹,我们就可以开始了

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-30
      • 2016-05-28
      • 1970-01-01
      • 2021-01-21
      相关资源
      最近更新 更多