【问题标题】:What is the proper way to access DB model's save method from within route handler function?从路由处理程序函数中访问数据库模型保存方法的正确方法是什么?
【发布时间】:2012-03-07 06:45:14
【问题描述】:

我注意到当使用 Express.js 创建项目时,路由处理函数现在与主“app.js”文件分离。它们现在被放置在 './routes/index.js' 中。鉴于这种情况,现在如何将记录保存到数据库(在这种情况下使用通过 Mongoose 访问的 MongoDB)。

传统上,'app.js' 中会有路由处理函数,例如:

//Create document 
app.post('/documents.:format?', function(req, res) {
  var d = new Document(req.body);
  d.user_id = req.currentUser.id;
  d.save(function() {
    switch (req.params.format) {
      case 'json':
        var data = d.toObject();
        // TODO: Backbone requires 'id', but can I alias it?
        data.id = data._id;
        res.send(data);
      break;

      default:
        req.flash('info', 'Document created');
        res.redirect('/documents');
    }
  });
});

在新的“布局”下,此类调用将更改为类似以下内容(在“app.js”文件中):

app.post('/documents.:format?', routes.add_documents);

所有实际处理都发生在文件“./route/index.js”中:

exports.add_documents = function(req, res){
  // Processing goes here!
};

我的问题是如何将原始路由处理函数合并到上面这个新的 add_documents 函数中?特别是,如何访问数据库模式模型(例如,创建“文档”的新实例)以便我可以访问数据库保存方法?

“app.js”的完整内容如下:

var express = require('express')
  , routes = require('./routes')
  , mongoose = require('mongoose')
  , models = require('./models')
  , Document;

var app = module.exports = express.createServer();

// Configuration

app.configure(function(){
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(__dirname + '/public'));
});

app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
  app.set('db-uri', 'mongodb://localhost/namecards');
});

app.configure('production', function(){
  app.use(express.errorHandler());
});

models.defineModels(mongoose, function() {
  app.Document = Document = mongoose.model('Document');
  db = mongoose.connect(app.set('db-uri'));
})

// Routes

app.get('/', routes.index);

app.get('/add', routes.add_form);

app.post('/add', routes.add_document);

app.listen(3000);
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);

“models.js”的内容

function defineModels(mongoose, fn) {
  var Schema = mongoose.Schema,
      ObjectId = Schema.ObjectId;

  /**
   * Model: Document
   */
  Document = new Schema({
    'surname': String,
    'given_name': String,
    'org': String,
    'phone': String
  });

  mongoose.model('Document', Document);

  fn();
}

exports.defineModels = defineModels; 

'./routes/index.js'的内容

/*
 * GET home page.
 */

exports.index = function(req, res){
  res.render('index', { title: 'Documents' });
};

/*
 * GET add contact page.
 */
exports.add_form = function(req, res){
  res.render('add', { title: 'Add Document' });
};

/*
 * POST add contact page.
 */
exports.add_document = function(req, res){
  // Save data to DB using mongoose.
};

【问题讨论】:

    标签: node.js express mongoose


    【解决方案1】:

    我通常称其为遵循 MVC 的控制器。

    我会将我的模型/模式导入控制器

    以下是我在 node/express 中做 MVC 的方式

    //controller
    
    module.exports = function (app, models) {
      var ctrl = {
        add_documents: function(req, res) {
             var document = new models.Document();
             document.something = something;
             document.save();
             res.end("Saved");
        }
      return crtl;
    }
    
    //sample model
    module.exports = function(mongoose) {
    var Document = new mongoose.Schema({
        field: value
    });
    var model = mongoose.model('Document', Document);
    return model;
     }
    
    
    //model loader
    module.exports = function(app, mongoose) {
    mongooseTypes = require("mongoose-types"); 
    mongooseTypes.loadTypes(mongoose);
    var obj = {
        Document: require('./models/document.js')(mongoose)
    }
    return obj;
    }
    
    //app.js
    var mongoose = require('mongoose');
    var models = require('./models')(app, mongoose);
    var routes = require('./routes')(app, models); 
    
    //routes
    module.exports = function(app, models) {
        var DocumentController = require("./controllers/documents")(app, models);
        app.post('/documents:.format', DocumentController.add_documents);
    }
    

    【讨论】:

    • 感谢您的快速回复。将模型传递给“控制器”是有意义的。我对如何在这里实施您的解决方案感到有些困惑。控制器代码去哪了?
    • //routes module.exports = function(app, models) { var DocumentController = require("./controllers/documents")(app, models); app.post('/documents:.format', DocumentController.add_documents); }
    • ^ 它是由路由加载的。
    • 恐怕我无法将上述示例转换为离散代码。如何划分这段代码?哪些代码段应该放到哪些文件中?我需要完全修改“app.js”吗?或者有没有办法在 Express 已经创建的结构中应用建议的解决方案的逻辑(控制器当前存储在 './routes/index.js' 中)?我修改了原始问题以揭示更多应用程序的整体结构。
    【解决方案2】:

    我找到了一种似乎可行的方法,它不需要对 Express 最初生成的代码进行大量更改。您所要做的就是将 mongoose 导入到包含路由处理函数(又名控制器)的文件中,然后在路由函数中加载相关模型(参见下面的 exports.addProcess)。

    这里是'./routes/index.js'的修改内容

    var mongoose = require('mongoose');
    var _ = require('underscore');
    
    
    /*
     * GET home page.
     */
    
    exports.index = function(req, res){
      res.render('index', { title: 'Documents' });
    };
    
    /*
     * POST add contact page.
     */
    exports.addProcess = function(req, res){
      var Document = mongoose.model('Document');
      var document= new Document();
      document.surname = req.body.surname;
      document.given_name = req.body.given_name;
      document.org = req.body.org;
      document.phone = req.body.phone;
      document.save(function(err) {
        res.redirect('/');
      });
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-04
      • 1970-01-01
      • 1970-01-01
      • 2021-10-31
      • 1970-01-01
      • 1970-01-01
      • 2021-07-06
      相关资源
      最近更新 更多