Skip to content
Toggle navigation
Projects
Groups
Snippets
Help
public
/
sequelize
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
不要怂,就是干,撸起袖子干!
Commit 29c9be37
authored
Oct 19, 2019
by
Simon Schick
Committed by
Sushant
Oct 19, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix(model): make .changed() deep aware (#10851)
1 parent
481bddd6
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
42 additions
and
27 deletions
lib/model.js
test/unit/instance/changed.test.js
lib/model.js
View file @
29c9be3
...
...
@@ -104,7 +104,7 @@ class Model {
this
.
dataValues
=
{};
this
.
_previousDataValues
=
{};
this
.
_changed
=
{}
;
this
.
_changed
=
new
Set
()
;
this
.
_modelOptions
=
this
.
constructor
.
options
;
this
.
_options
=
options
||
{};
...
...
@@ -160,7 +160,6 @@ class Model {
delete
defaults
[
this
.
constructor
.
_timestampAttributes
.
deletedAt
];
}
if
(
Object
.
keys
(
defaults
).
length
)
{
for
(
key
in
defaults
)
{
if
(
values
[
key
]
===
undefined
)
{
this
.
set
(
key
,
Utils
.
toDefaultValue
(
defaults
[
key
],
this
.
sequelize
.
options
.
dialect
),
{
raw
:
true
});
...
...
@@ -168,7 +167,6 @@ class Model {
}
}
}
}
this
.
set
(
values
,
options
);
}
...
...
@@ -2450,8 +2448,9 @@ class Model {
const
hasPrimary
=
this
.
primaryKeyField
in
values
||
this
.
primaryKeyAttribute
in
values
;
const
instance
=
this
.
build
(
values
);
const
changed
=
Array
.
from
(
instance
.
_changed
);
if
(
!
options
.
fields
)
{
options
.
fields
=
Object
.
keys
(
instance
.
_changed
)
;
options
.
fields
=
changed
;
}
return
Promise
.
try
(()
=>
{
...
...
@@ -2460,7 +2459,7 @@ class Model {
}
}).
then
(()
=>
{
// Map field names
const
updatedDataValues
=
_
.
pick
(
instance
.
dataValues
,
Object
.
keys
(
instance
.
_changed
)
);
const
updatedDataValues
=
_
.
pick
(
instance
.
dataValues
,
changed
);
const
insertValues
=
Utils
.
mapValueFieldNames
(
instance
.
dataValues
,
Object
.
keys
(
instance
.
rawAttributes
),
this
);
const
updateValues
=
Utils
.
mapValueFieldNames
(
updatedDataValues
,
options
.
fields
,
this
);
const
now
=
Utils
.
now
(
this
.
sequelize
.
options
.
dialect
);
...
...
@@ -3477,7 +3476,7 @@ class Model {
setDataValue
(
key
,
value
)
{
const
originalValue
=
this
.
_previousDataValues
[
key
];
if
(
!
Utils
.
isPrimitive
(
value
)
&&
value
!==
null
||
value
!==
originalValue
)
{
if
(
!
_
.
isEqual
(
value
,
originalValue
)
)
{
this
.
changed
(
key
,
true
);
}
...
...
@@ -3654,7 +3653,7 @@ class Model {
// custom setter should have changed value, get that changed value
// TODO: v5 make setters return new value instead of changing internal store
const
newValue
=
this
.
dataValues
[
key
];
if
(
!
Utils
.
isPrimitive
(
newValue
)
&&
newValue
!==
null
||
newValue
!==
originalValue
)
{
if
(
!
_
.
isEqual
(
newValue
,
originalValue
)
)
{
this
.
_previousDataValues
[
key
]
=
originalValue
;
this
.
changed
(
key
,
true
);
}
...
...
@@ -3707,7 +3706,7 @@ class Model {
// Check for data type type comparators
!
(
value
instanceof
Utils
.
SequelizeMethod
)
&&
this
.
constructor
.
_dataTypeChanges
[
key
]
&&
this
.
constructor
.
_dataTypeChanges
[
key
].
call
(
this
,
value
,
originalValue
,
options
)
||
// Check default
!
this
.
constructor
.
_dataTypeChanges
[
key
]
&&
(
!
Utils
.
isPrimitive
(
value
)
&&
value
!==
null
||
value
!==
originalValue
)
!
this
.
constructor
.
_dataTypeChanges
[
key
]
&&
!
_
.
isEqual
(
value
,
originalValue
)
)
)
{
this
.
_previousDataValues
[
key
]
=
originalValue
;
...
...
@@ -3731,23 +3730,42 @@ class Model {
*
* If changed is called without an argument and no keys have changed, it will return `false`.
*
* Please note that this function will return `false` when a property from a nested (for example JSON) property
* was edited manually, you must call `changed('key', true)` manually in these cases.
* Writing an entirely new object (eg. deep cloned) will be detected.
*
* @example
* ```
* const mdl = await MyModel.findOne();
* mdl.myJsonField.a = 1;
* console.log(mdl.changed()) => false
* mdl.save(); // this will not save anything
* mdl.changed('myJsonField', true);
* console.log(mdl.changed()) => ['myJsonField']
* mdl.save(); // will save
* ```
*
* @param {string} [key] key to check or change status of
* @param {any} [value] value to set
*
* @returns {boolean|Array}
*/
changed
(
key
,
value
)
{
if
(
key
)
{
if
(
value
!==
undefined
)
{
this
.
_changed
[
key
]
=
value
;
if
(
key
===
undefined
)
{
if
(
this
.
_changed
.
size
>
0
)
{
return
Array
.
from
(
this
.
_changed
);
}
return
false
;
}
if
(
value
===
true
)
{
this
.
_changed
.
add
(
key
);
return
this
;
}
return
this
.
_changed
[
key
]
||
false
;
if
(
value
===
false
)
{
this
.
_changed
.
delete
(
key
);
return
this
;
}
const
changed
=
Object
.
keys
(
this
.
dataValues
).
filter
(
key
=>
this
.
changed
(
key
));
return
changed
.
length
?
changed
:
false
;
return
this
.
_changed
.
has
(
key
);
}
/**
...
...
test/unit/instance/changed.test.js
View file @
29c9be3
...
...
@@ -78,21 +78,18 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
expect
(
user
.
changed
(
'birthday'
)).
to
.
equal
(
false
);
});
it
(
'should return true for changed JSON with same object'
,
function
()
{
const
user
=
this
.
User
.
build
({
meta
:
{
city
:
'Copenhagen'
}
it
(
'should not detect changes when equal'
,
function
()
{
for
(
const
value
of
[
null
,
1
,
'asdf'
,
new
Date
(),
[],
{},
Buffer
.
from
(
''
)])
{
const
t
=
new
this
.
User
({
json
:
value
},
{
isNewRecord
:
false
,
raw
:
true
});
const
meta
=
user
.
get
(
'meta'
);
meta
.
city
=
'Stockholm'
;
user
.
set
(
'meta'
,
meta
);
expect
(
user
.
changed
(
'meta'
)).
to
.
equal
(
true
);
t
.
json
=
value
;
expect
(
t
.
changed
(
'json'
)).
to
.
be
.
false
;
expect
(
t
.
changed
()).
to
.
be
.
false
;
}
});
it
(
'should return true for JSON dot.separated key with changed values'
,
function
()
{
...
...
Write
Preview
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment