42

Works:

var mongoose = require('mongoose');

var db = function() {
  return {
    config: function(conf) {
      mongoose.connect('mongodb://' + conf.host + '/' + conf.database);
      var db = mongoose.connection;
      db.on('error', console.error.bind(console, 'connection error:'));
      db.once('open', function callback() {
        console.log('db connection open');
      });
    }
  };
};

module.exports = db();

Doesn't work:

var mongoose = require('mongoose');

var db = function() {
  return {
    config: function(conf) {
      var db = mongoose.createConnection('mongodb://' + conf.host + '/' + conf.database);
      db.on('error', console.error.bind(console, 'connection error:'));
      db.once('open', function callback() {
        console.log('db connection open');
      });
    }
  };
};

module.exports = db();

Insert code:

'use strict';


var mongoose = require('mongoose'),
User = mongoose.model('User'),
p = require('../lib/promise');

...
app.post('/user', function (req, res) {
  res.format({
    json: function () {
      //extract the user from the req
      try {
        var user = new User();
        user.firstName = req.body.firstName;
        user.lastName = req.body.lastName;
        user.userName = req.body.userName;
        user.password = req.body.password;
        user.email = req.body.email;

        user.save(function(err, data) {
        //omitted
...
Ilyas karim
  • 4,592
  • 4
  • 33
  • 47
binarygiant
  • 6,362
  • 10
  • 50
  • 73

2 Answers2

90

Unfortunately, this isn't a simple refactor.

1) .createConnection vs .connect

When using .createConnection, you access models via the explicit connection you create with this call.

This means that instead of User = mongoose.model(...) you need User = db.model(...).

Examples (one, two, three, four) show this isn't complicated but the change is subtle enough that many people miss it. The docs aren't super clear on this either, which is probably the root cause.

2) your kraken app & .createConnection

If you are building on one of the kraken examples, you'll need to make several changes.

  1. Change the code around .createConnection so you can access the object that is returned. In the current form, you are returning an object with a config function but you don't return the connection object that .createConnection generates.
  2. Update index.js if you change the way you configure/create the connection in db.config. You might be able to avoid this, but I suspect you'll rewrite the entire db.js around the new call.
  3. Make sure code/controllers working with models have access to the object your .createConnection returned. This means both a way to access the object and changing anyplace you set a variable so it uses the format var xyz = db.model('XYZ'), etc.

Sorry that there isn't a simple one-line answer...

Community
  • 1
  • 1
Matthew Bakaitis
  • 11,600
  • 7
  • 43
  • 53
  • 2
    Thank you so much, was driving myself crazy with this one. I agree that the documentation causes much of the problem. – Seth Sep 28 '15 at 16:03
  • 16
    This is why MongoDB and Mongoose gets bad rep. – lazlojuly May 20 '16 at 10:54
  • 1
    There are indeed many questions around with this exact problem! I've just submitted an issue on github as this creates too many frustrations https://github.com/Automattic/mongoose/issues/4413 – cortopy Aug 14 '16 at 10:00
  • 2
    as normal, I always use mongoose.model('ModelName', schemaName) and export this model to use at other files. If use db.model('ModelName'), how I can reuse old code? And I have to always pass db via parameter to function and use db.model('ModelName') each time action to db ? I very inconvenience – Vũ Anh Dũng Sep 01 '21 at 07:29
0

You need to use .createConnection, NOT .connect

BAD:

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/myapp', {useNewUrlParser: true});
var MyModel = mongoose.model('Test', new Schema({ name: String }));
// Works
MyModel.findOne(function(error, result) { /* ... */ });

GOOD:

const mongoose = require('mongoose');
var connection = mongoose.createConnection('mongodb://localhost:27017/myapp',
                                           {useNewUrlParser: true});
var MyModel = connection.model('Test', new Schema({ name: String }));
// Works
MyModel.findOne(function(error, result) { /* ... */ });

original post: https://dev.to/maixuanhan/stop-using-the-mongoose-s-default-connection-4nnj

I have a video on my channel on how to do it: https://youtu.be/mvot9o0BgU8

fruitloaf
  • 1,628
  • 15
  • 10