Automattic / mongoose

MongoDB object modeling designed to work in an asynchronous environment.
https://mongoosejs.com
MIT License
26.85k stars 3.82k forks source link

Mongoose npm cache #2091

Closed pvencill closed 8 years ago

pvencill commented 10 years ago

This might be an edge case, but I'm noticing a problem that I think has to do with how mongoose is cached in npm.

I have a plugin I've written which needs to be able to query the database for documents based on the current Schema. As far as I can tell, the best way to do this is to get a Model from mongoose (e.g. mongoose.model('mymodel'); and then use the query API for validation purposes (i.e. validate currently saving model based on other state in the DB).

This works fine, and the plugins tests all pass.

The problem is when installed as an npm module in another project, the call to var mongoose = require('mongoose')' doesn't appear to resolve to the same object in the plugin as it is in the consuming code. I don't know this for a fact, but am inferring that based on the fact that the calling code declares models and associates them with mongoose via mongoose.model('MyModel', mySchema); but if I console.log the defined schemas from within my plugin, it looks like mongoose isn't populated with any schemas, and in fact doesn't get the connection from the calling code either.

Should I be passing the mongoose instance (or a connection instance) to the plugin via the options param? That feels odd to me, but I'm not sure how else to ensure they have the same scope (even worse when you consider the different ways to do connections).

pvencill commented 10 years ago

Found a solution, would still be interested in knowing if it's a safe approach however.

My new approach is to call document.collection.conn.model() vice mongoose.model(). Where document is the document instance being saved. Seems to be working for now, but I'd like to know if there's edge cases where it wouldn't.

vkarpov15 commented 10 years ago

Hi,

Is your plugin a separate npm module that lists mongoose as a dependency? In that case, if a client of your plugin has both mongoose and your plugin in their package.json dependencies, your plugin will be using a separate mongoose object. It may even be using a different version of mongoose, because of how npm installs modules.

vkarpov15 commented 10 years ago

I think the more correct way would be for your plugin to accept the Model as a parameter.

On Mon, May 19, 2014 at 9:30 PM, pvencill notifications@github.com wrote:

@vkarpov15 https://github.com/vkarpov15 yes, that's exactly what I suggested was the case in my original question. The follow-up was whether it's a valid approach to use the connection that's attached to the document's collection property in order to do what I need to.

— Reply to this email directly or view it on GitHubhttps://github.com/LearnBoost/mongoose/issues/2091#issuecomment-43577679 .

pvencill commented 10 years ago

@vkarpov15 I'm not sure how you could do that, perhaps you can explain it to me? At the point in which the plugin is applied, there is no Model to pass as a parameter, and while this may not be common to everyone in the apps I've built the call to mongoose.model('Model', mySchema) doesn't always happen in the same file as the actual creation of the schema (due to, for example, having all schemas in one folder, and only those promoted to actual 'models' (vice those which are embedded in other models) having the mongoose.model call applied in a different file for the sake of clarity / consistency.