Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Defaults corruption #393

Open
cha0s opened this issue Apr 5, 2014 · 4 comments
Open

Defaults corruption #393

cha0s opened this issue Apr 5, 2014 · 4 comments
Milestone

Comments

@cha0s
Copy link
Contributor

cha0s commented Apr 5, 2014

Any defaults that contain a reference will be corrupted when a value is set into the corresponding attribute. Here's a short example:

{Schema} = require 'jugglingdb'

schema = new Schema require('jugglingdb/lib/adapters/memory'), {}

Test = schema.define 'Test',

    attribute:
        type: Schema.JSON
        default: {}

test = new Test()

test.attribute['foo'] = 'bar'

test2 = new Test()

throw new Error "Corrupted default" if test2.attribute['foo'] is 'bar'

...and in JS in case you hate Coffee:

(function() {
  var Schema, Test, schema, test, test2;

  Schema = require('jugglingdb').Schema;

  schema = new Schema(require('jugglingdb/lib/adapters/memory'), {});

  Test = schema.define('Test', {
    attribute: {
      type: Schema.JSON,
      "default": {}
    }
  });

  test = new Test();

  test.attribute['foo'] = 'bar';

  test2 = new Test();

  if (test2.attribute['foo'] === 'bar') {
    throw new Error("Corrupted default");
  }

}).call(this);

You can see in model.js that the getDefault function simply returns the default, which in the case of Schema.JSON (and possibly others) is a reference to the default object. This means that when a key is set in a property of a specific model instance, the change will propagate up to (and corrupt) the default object.

I'm not sure what the correct fix is. I am working around this in my own code by using the function version of default, and returning an empty object from a simple closure.

@anatoliychakkaev
Copy link
Collaborator

Make it function that returns object.

On 5 April 2014 08:30, Ruben Rodriguez [email protected] wrote:

Any defaults that contain a reference will be corrupted when a value is
set into the corresponding attribute. Here's a short example:

{Schema} = require 'jugglingdb'
schema = new Schema require('jugglingdb/lib/adapters/memory'), {}
Test = schema.define 'Test',

attribute:
    type: Schema.JSON
    default: {}

test = new Test()
test.attribute['foo'] = 'bar'
test2 = new Test()
throw new Error "Corrupted default" if test2.attribute['foo'] is 'bar'

...and in JS in case you hate Coffee:

(function() {
var Schema, Test, schema, test, test2;

Schema = require('jugglingdb').Schema;

schema = new Schema(require('jugglingdb/lib/adapters/memory'), {});

Test = schema.define('Test', {
attribute: {
type: Schema.JSON,
"default": {}
}
});

test = new Test();

test.attribute['foo'] = 'bar';

test2 = new Test();

if (test2.attribute['foo'] === 'bar') {
throw new Error("Corrupted default");
}
}).call(this);

You can see in model.jshttps://github.com/cha0s/promised-jugglingdb/blob/master/lib/model.js#L109that the getDefault function simply returns the default, which in the case
of Schema.JSON (and possibly others) is a reference to the default object.
This means that when a key is set in a property of a specific model
instance, the change will propagate up to (and corrupt) the default object.

I'm not sure what the correct fix is. I am working around this in my own
code by using the function version of default, and returning an empty
object from a simple closure.

Reply to this email directly or view it on GitHubhttps://github.com//issues/393
.

@randunel
Copy link
Collaborator

randunel commented Apr 8, 2014

This is an excerpt from docs/schema.md:

var User = schema.define('User', {
    email: { type: String, limit: 150, index: true },
    password: { type: String, limit: 50 },
    birthDate: Date,
    registrationDate: {
        type: Date,
        default: function () { return new Date }
    },
    activated: { type: Boolean, default: false }
}, {
    table: 'users'
});

Take a look at default: function() {return new Date}

@cha0s
Copy link
Contributor Author

cha0s commented Apr 9, 2014

@1602 Yeah, I did use the callback version.

@randunel Yeah, that one is a bit different because semantically it matters when you create a Date object.

How do you guys feel about making a special note about this in the docs? I could see other people running into this.

@randunel
Copy link
Collaborator

randunel commented Apr 9, 2014

Yup, makes sense.

@1602 1602 added this to the v2.0.0 milestone Mar 16, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants