Using sequelize to store and retrieve JSON objects within a Model/Instance

Problem

I'm looking to leverage sequelize on a big project, and was hoping I could use it to store a JSON Object as a property in a Model.

I feel like I'm struggling with this, but perhaps I'm missing something simple?

I'm defining a model (Context) as follows:

var contextProperties = {

  contextName: { type: Sequelize.STRING, validate: { is: ["[a-z]",'i'], notEmpty: true } },

  _trackList: {type: Sequelize.TEXT},    
  trackList: {type: Sequelize.TEXT}

}

var contextGetSet = {

  getterMethods: {
    trackList: function(){
      return JSON.parse(this._trackList);
    }
  },

  setterMethods: {
    trackList: function(v){
      this._trackList = JSON.stringify(v);
    }
  }

};

var Context = sequelize.define('Context', contextProperties, contextGetSet);

Now when I create my Context, it seems to work before I save.

var contextMain;

Context.create({contextName: "Whatever"}).success(function (context){

  contextMain = context;

  contextMain.trackList = { atrackList: "1111", anotherTrackList: 2872 };
  console.log(constextMain.trackList);
  //logs { atrackList: "1111", anotherTrackList: 2872 } as expected


  contextMain.save().success(function (contextSaved){
    console.log(contextSaved.values);
    //all values are null except for the contextName
  });

});

So the JSON IS setting right, but the object returned by the save().success() method does not seem to have the proper values of what I set it to.

When I log the object returned by the save().success() method (ie. contextSaved.values) the object looks like this:

{ contextName: 'Whatever',
  _trackList: 'null',
  trackList: null,
  id: 6,
  createdAt: Fri Dec 06 2013 15:57:39 GMT-0500 (EST),
  updatedAt: Fri Dec 06 2013 15:57:39 GMT-0500 (EST)
}

Everything is null!!

Even more weird is that when I look at the save SQL query made to save contextMain, it seems to be saving right!

Executing: UPDATE "Contexts" SET "contextName"='Whatever', "_trackList"='{"atrackList":"1111","anotherTrackList":2872}', "trackList"=NULL,"id"=7, "createdAt"='2013-12-06 20:59:39.278 +00:00', "updatedAt"='2013
-12-06 20:59:39.294 +00:00' WHERE "id"=7 RETURNING *

Notice that: "_trackList"='{"atrackList":"1111","anotherTrackList":2872}'

Also when I look at the actual SQL row for it, it does have the stringified JSON object in there!

If I load the Context using sequelize though...

Context.findAll().success(function(contexts) {
  console.log(JSON.stringify(contexts))
  // also displays null for _trackList and trackList
});

So very strange. Any help greatly greatly appreciated!! Thanks so much! Sorry this post is so long!

Problem courtesy of: Arjun Mehta

Solution

This was apparently a bug with the getters and setters for the objects and resolved recently: https://github.com/sequelize/sequelize/issues/759

Solution courtesy of: Arjun Mehta

Discussion

Can you check if the setterMethod that is running JSON.stringify is getting called? Maybe its trying to insert as an object not a string?

More broadly, have you considered MongoDb? There may be other reasons why it isn't appealing for you, but just from this glimpse into the project, it looks like it would have real advantages--chiefly not having to parse json in both directions... but beyond that you'd be able to do things like query with the values inside that object, which might prove useful later on.

Discussion courtesy of: Zeke Alexandre Nierenberg

This recipe can be found in it's original form on Stack Over Flow.