从路由处理函数中访问DB模型的save方法的正确方法是什么?

时间:2012-03-07 06:45:15

标签: node.js express mongoose

我注意到当使用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函数中?特别是,如何访问数据库模式模型(例如,创建“Document”的新实例)以便我可以访问数据库保存方法?

'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.
};

2 个答案:

答案 0 :(得分:0)

我通常称这是一个跟随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);
}

答案 1 :(得分:0)

我找到了一种似乎有效的方法,它不会对最初由Express生成的代码进行大量更改。您所要做的就是将mongoose导入到包含路由处理函数a.k.a.controller的文件中,然后在路由函数中加载相关模型(请参阅下面的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('/');
  });
};