Sunday, February 1, 2015

Creation method in Mongoose.js, alternative to custom constructor or hooks

Creation method or factory method is a neat way of creating objects in the same way by using the object's well-named static method instead of constructor. While similar, creation method should not to be confused with factory method pattern, which involves the concrete implementation of created objects). If you'd like to know more about creation method's benefits and application I highly recommend Joshua Kerievsky's Refactoring to Patterns.

Here's how this alternative to custom constructor or hooks can work in Mongoose. Let's use an Article model in Mean.js app generated by Yeoman as an example:

'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
 Schema = mongoose.Schema;

/**
 * Article Schema
 */
var ArticleSchema = new Schema({
 created: {
  type: Date,
  default: Date.now
 },
 title: {
  type: String,
  default: '',
  trim: true,
  required: 'Title cannot be blank'
 },
 url: {
  type: String,
  trim: true,
  default: '',
  required: 'Url cannot be blank'
 },
 content: {
  type: String,
  default: '',
  trim: true
 },
 user: {
  type: Schema.ObjectId,
  ref: 'User'
 }
});

mongoose.model('Article', ArticleSchema);

Let's say we'd like article to have an url field, which we'd like to generate from the title. We'd like to avoid copying the url generation code everytime we'd like to create an article. One way to do this is to create a creation method which does that.

Since all static methods have to be defined before the model class is created creating a creation method the following won't work:

/** Schema definition. */

var Article = mongoose.model('Article', ArticleSchema);

ArticleSchema.schema.createInstance = function (user, title, content) {
 return new Article({
  user: user,
  title: title,
  content: content,
  url: title.replace(new RegExp(' ', 'g'), '-')
 });
};

Instead we can simply fetch the model using mongoose.model. Here's a working example of a creation method:

/** Schema definition. */

ArticleSchema.schema.createInstance = function (user, title, content) {
 var Article = mongoose.model('Article');
 return new Article({
  user: user,
  title: title,
  content: content,
  url: title.replace(new RegExp(' ', 'g'), '-')
 });
};

mongoose.model('Article', ArticleSchema);

No comments:

Post a Comment