Setting created_by user with a Mongoose plugin using session

Im using Node.js and I'm trying to make a Mongoose plugin which sets a created_by value to the current logged-in user-id. The user is stored in the session.

lastModifiedPlugin = (schema, options) ->
  schema.add 
    created_by: 
      type: ObjectId
      default: -> 
        session.user._id // Need access to session
    created_at:
      type: Date
      default: Date.now

I'm using connect-mongo for a MongoDB session storage.

express = require "express"
MongoStore = require("connect-mongo")(express)

I know how to get the session from a request object or using the session store when you have a sessionID. The problem is: I dont have a request, nor session, nor sessionId in this case.

My question: How do you get the session in a Mongoose plugin? Or how to implement this functionality in a different -hopefully just as easy- way? It seems to me like a very common use-case.

You're close. As you've mentioned, you don't have req and all the attached session goodies available in your plug-in definition.

These values are available a bit later however: when you save your model.

So instead of setting a default, you want your model to automatically include the user_id when a model is being saved.

See whether .pre('save', ...) is enough of a hint to figure this out.


I've tried it out myself using mongoose middleware. Even using magic tricks (Intercepting and mutating method arguments), I can't get a simple enough solution... I end up passing the req object to .save() (the middleware can then extract the session's user_id)... but this addition to .save() breaks the magic-ness of the middleware.

lastModifiedPlugin = (schema, options) ->
  schema.add 
    created_by: ObjectId
    created_at:
      type: Date
      default: Date.now
  schema.pre 'save', (next, req) -> # No callback required here.
    this.created_by = req?.session?.user_id?
    next()

when using this:

app.get '/', (req, res) ->
  # make an instance of whatever uses the plugin
  instance.save req, (err) -> # Callback required here
    # Callback to handle errors

I considered making an express middleware that removes the schema's middleware and adds a new schema middleware that knows the request object... but that solution is ridiculously hacky and is likely to break other mongoose plug-ins you're trying to use.