Merge pull request #1706 from strongloop/fix/default-value-in-response-2x

Do not apply default values on data from database
This commit is contained in:
Miroslav Bajtoš 2019-04-09 18:16:34 +02:00 committed by GitHub
commit ddd483ac3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 163 additions and 3 deletions

View File

@ -1065,8 +1065,15 @@ DataAccessObject.findOrCreate = function findOrCreate(query, data, options, cb)
var obj, Model = self.lookupModel(data);
if (data) {
obj = new Model(data, {fields: query.fields, applySetters: false,
persisted: true});
var ctorOpts = {
fields: query.fields,
applySetters: false,
persisted: true,
};
if (Model.settings.applyDefaultsOnReads === false) {
ctorOpts.applyDefaultValues = false;
}
obj = new Model(data, ctorOpts);
}
if (created) {
@ -1936,7 +1943,15 @@ DataAccessObject.find = function find(query, options, cb) {
if (!err && Array.isArray(data)) {
async.map(data, function(item, next) {
var Model = self.lookupModel(item);
var obj = new Model(item, {fields: query.fields, applySetters: false, persisted: true});
var ctorOpts = {
fields: query.fields,
applySetters: false,
persisted: true,
};
if (Model.settings.applyDefaultsOnReads === false) {
ctorOpts.applyDefaultValues = false;
}
var obj = new Model(item, ctorOpts);
if (query && query.include) {
if (query.collect) {

View File

@ -579,6 +579,75 @@ describe('basic-querying', function() {
sample(['id']).expect(['id']);
sample(['email']).expect(['email']);
});
it('applies default values by default', function() {
// Backwards compatibility, see
// https://github.com/strongloop/loopback-datasource-juggler/issues/1692
// Initially, all Players were always active, no property was needed
var Player = db.define('Player', {name: String});
var created;
return db.automigrate('Player')
.then(function() { return Player.create({name: 'Pen'}); })
.then(function(result) {
created = result;
// Later on, we decide to introduce `active` property
Player.defineProperty('active', {
type: Boolean,
default: false,
});
return db.autoupdate('Player');
})
.then(function() {
// And query existing data
return Player.findOne();
})
.then(function(found) {
should(found.toObject().active).be.oneOf([
// For databases supporting `undefined` value,
// we convert `undefined` to property default.
false,
// For databases representing `undefined` as `null` (e.g. SQL),
// we treat `null` as a defined value and don't apply defaults.
null,
]);
});
});
it('preserves empty values from the database when "applyDefaultsOnReads" is false', function() {
// https://github.com/strongloop/loopback-datasource-juggler/issues/1692
// Initially, all Players were always active, no property was needed
var Player = db.define(
'Player',
{name: String},
{applyDefaultsOnReads: false}
);
var created;
return db.automigrate('Player')
.then(function() { return Player.create({name: 'Pen'}); })
.then(function(result) {
created = result;
// Later on, we decide to introduce `active` property
Player.defineProperty('active', {
type: Boolean,
default: false,
});
return db.autoupdate('Player');
})
.then(function() {
// And query existing data
return Player.findOne();
})
.then(function(found) {
should(found.toObject().active).be.oneOf([
undefined, // databases supporting `undefined` value
null, // databases representing `undefined` as `null`
]);
});
});
});
describe('count', function() {

View File

@ -1240,6 +1240,82 @@ describe('manipulation', function() {
})
.catch(done);
});
it('applies default values on returned data', function() {
// Backwards compatibility, see
// https://github.com/strongloop/loopback-datasource-juggler/issues/1692
// Initially, all Players were always active, no property was needed
var Player = db.define('Player', {name: String});
var created;
return db.automigrate('Player')
.then(function() { return Player.create({name: 'Pen'}); })
.then(function(result) {
created = result;
// Later on, we decide to introduce `active` property
Player.defineProperty('active', {
type: Boolean,
default: false,
});
return db.autoupdate('Player');
})
.then(function() {
// and findOrCreate an existing record
return Player.findOrCreate({id: created.id}, {name: 'updated'});
})
.then(function(result) {
var found = result[0];
// Backwards-compatibility
// When Pen does not have "active" flag set, we change it to default
should(found.toObject().active).be.oneOf([
// For databases supporting `undefined` value,
// we convert `undefined` to property default.
false,
// For databases representing `undefined` as `null` (e.g. SQL),
// we treat `null` as a defined value and don't apply defaults.
null,
]);
});
});
it('preserves empty values from the database when "applyDefaultsOnReads" is false', function() {
// https://github.com/strongloop/loopback-datasource-juggler/issues/1692
// Initially, all Players were always active, no property was needed
var Player = db.define(
'Player',
{name: String},
{applyDefaultsOnReads: false}
);
var created;
return db.automigrate('Player')
.then(function() { return Player.create({name: 'Pen'}); })
.then(function(result) {
created = result;
// Later on, we decide to introduce `active` property
Player.defineProperty('active', {
type: Boolean,
default: false,
});
return db.autoupdate('Player');
})
.then(function() {
// And findOrCreate an existing record
return Player.findOrCreate({id: created.id}, {name: 'updated'});
})
.then(function(result) {
var found = result[0];
should(found.toObject().active).be.oneOf([
undefined, // databases supporting `undefined` value
null, // databases representing `undefined` as `null`
]);
});
});
});
describe('destroy', function() {