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 d041e77e
authored
Jul 31, 2019
by
Gabe Gorelick
Committed by
Sushant
Jul 31, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix(model): destroying paranoid models with custom deletedAt (#11255)
1 parent
c32ac014
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
115 additions
and
21 deletions
lib/model.js
test/integration/instance.test.js
test/integration/instance/destroy.test.js
test/unit/model/destroy.test.js
lib/model.js
View file @
d041e77
...
@@ -4052,29 +4052,19 @@ class Model {
...
@@ -4052,29 +4052,19 @@ class Model {
const
where
=
this
.
where
(
true
);
const
where
=
this
.
where
(
true
);
if
(
this
.
constructor
.
_timestampAttributes
.
deletedAt
&&
options
.
force
===
false
)
{
if
(
this
.
constructor
.
_timestampAttributes
.
deletedAt
&&
options
.
force
===
false
)
{
const
attribute
=
this
.
constructor
.
rawAttributes
[
this
.
constructor
.
_timestampAttributes
.
deletedAt
];
const
attributeName
=
this
.
constructor
.
_timestampAttributes
.
deletedAt
;
const
field
=
attribute
.
field
||
this
.
constructor
.
_timestampAttributes
.
deletedAt
;
const
attribute
=
this
.
constructor
.
rawAttributes
[
attributeName
];
const
values
=
Utils
.
mapValueFieldNames
(
this
.
dataValues
,
this
.
changed
()
||
[],
this
.
constructor
);
const
defaultValue
=
Object
.
prototype
.
hasOwnProperty
.
call
(
attribute
,
'defaultValue'
)
values
[
field
]
=
new
Date
();
where
[
field
]
=
Object
.
prototype
.
hasOwnProperty
.
call
(
attribute
,
'defaultValue'
)
?
attribute
.
defaultValue
?
attribute
.
defaultValue
:
null
;
:
null
;
const
currentValue
=
this
.
getDataValue
(
attributeName
);
const
undefinedOrNull
=
currentValue
==
null
&&
defaultValue
==
null
;
if
(
undefinedOrNull
||
_
.
isEqual
(
currentValue
,
defaultValue
))
{
// only update timestamp if it wasn't already set
this
.
setDataValue
(
attributeName
,
new
Date
());
}
this
.
setDataValue
(
field
,
values
[
field
]);
return
this
.
save
(
_
.
defaults
({
hooks
:
false
},
options
));
return
this
.
constructor
.
QueryInterface
.
update
(
this
,
this
.
constructor
.
getTableName
(
options
),
values
,
where
,
_
.
defaults
({
hooks
:
false
,
model
:
this
.
constructor
},
options
)
).
then
(([
results
,
rowsUpdated
])
=>
{
if
(
this
.
constructor
.
_versionAttribute
&&
rowsUpdated
<
1
)
{
throw
new
sequelizeErrors
.
OptimisticLockError
({
modelName
:
this
.
constructor
.
name
,
values
,
where
});
}
return
results
;
});
}
}
return
this
.
constructor
.
QueryInterface
.
delete
(
this
,
this
.
constructor
.
getTableName
(
options
),
where
,
Object
.
assign
({
type
:
QueryTypes
.
DELETE
,
limit
:
null
},
options
));
return
this
.
constructor
.
QueryInterface
.
delete
(
this
,
this
.
constructor
.
getTableName
(
options
),
where
,
Object
.
assign
({
type
:
QueryTypes
.
DELETE
,
limit
:
null
},
options
));
}).
tap
(()
=>
{
}).
tap
(()
=>
{
...
...
test/integration/instance.test.js
View file @
d041e77
...
@@ -685,5 +685,109 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
...
@@ -685,5 +685,109 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
expect
(
user
.
username
).
to
.
equal
(
'Peter'
);
expect
(
user
.
username
).
to
.
equal
(
'Peter'
);
});
});
});
});
it
(
'supports custom deletedAt field'
,
function
()
{
const
ParanoidUser
=
this
.
sequelize
.
define
(
'ParanoidUser'
,
{
username
:
DataTypes
.
STRING
,
destroyTime
:
DataTypes
.
DATE
},
{
paranoid
:
true
,
deletedAt
:
'destroyTime'
});
return
ParanoidUser
.
sync
({
force
:
true
}).
then
(()
=>
{
return
ParanoidUser
.
create
({
username
:
'username'
});
}).
then
(
user
=>
{
return
user
.
destroy
();
}).
then
(
user
=>
{
expect
(
user
.
destroyTime
).
to
.
be
.
ok
;
expect
(
user
.
deletedAt
).
to
.
not
.
be
.
ok
;
return
user
.
restore
();
}).
then
(
user
=>
{
expect
(
user
.
destroyTime
).
to
.
not
.
be
.
ok
;
return
ParanoidUser
.
findOne
({
where
:
{
username
:
'username'
}
});
}).
then
(
user
=>
{
expect
(
user
).
to
.
be
.
ok
;
expect
(
user
.
destroyTime
).
to
.
not
.
be
.
ok
;
expect
(
user
.
deletedAt
).
to
.
not
.
be
.
ok
;
});
});
it
(
'supports custom deletedAt field name'
,
function
()
{
const
ParanoidUser
=
this
.
sequelize
.
define
(
'ParanoidUser'
,
{
username
:
DataTypes
.
STRING
,
deletedAt
:
{
type
:
DataTypes
.
DATE
,
field
:
'deleted_at'
}
},
{
paranoid
:
true
});
return
ParanoidUser
.
sync
({
force
:
true
}).
then
(()
=>
{
return
ParanoidUser
.
create
({
username
:
'username'
});
}).
then
(
user
=>
{
return
user
.
destroy
();
}).
then
(
user
=>
{
expect
(
user
.
dataValues
.
deletedAt
).
to
.
be
.
ok
;
expect
(
user
.
dataValues
.
deleted_at
).
to
.
not
.
be
.
ok
;
return
user
.
restore
();
}).
then
(
user
=>
{
expect
(
user
.
dataValues
.
deletedAt
).
to
.
not
.
be
.
ok
;
expect
(
user
.
dataValues
.
deleted_at
).
to
.
not
.
be
.
ok
;
return
ParanoidUser
.
findOne
({
where
:
{
username
:
'username'
}
});
}).
then
(
user
=>
{
expect
(
user
).
to
.
be
.
ok
;
expect
(
user
.
deletedAt
).
to
.
not
.
be
.
ok
;
expect
(
user
.
deleted_at
).
to
.
not
.
be
.
ok
;
});
});
it
(
'supports custom deletedAt field and database column'
,
function
()
{
const
ParanoidUser
=
this
.
sequelize
.
define
(
'ParanoidUser'
,
{
username
:
DataTypes
.
STRING
,
destroyTime
:
{
type
:
DataTypes
.
DATE
,
field
:
'destroy_time'
}
},
{
paranoid
:
true
,
deletedAt
:
'destroyTime'
});
return
ParanoidUser
.
sync
({
force
:
true
}).
then
(()
=>
{
return
ParanoidUser
.
create
({
username
:
'username'
});
}).
then
(
user
=>
{
return
user
.
destroy
();
}).
then
(
user
=>
{
expect
(
user
.
dataValues
.
destroyTime
).
to
.
be
.
ok
;
expect
(
user
.
dataValues
.
deletedAt
).
to
.
not
.
be
.
ok
;
expect
(
user
.
dataValues
.
destroy_time
).
to
.
not
.
be
.
ok
;
return
user
.
restore
();
}).
then
(
user
=>
{
expect
(
user
.
dataValues
.
destroyTime
).
to
.
not
.
be
.
ok
;
expect
(
user
.
dataValues
.
destroy_time
).
to
.
not
.
be
.
ok
;
return
ParanoidUser
.
findOne
({
where
:
{
username
:
'username'
}
});
}).
then
(
user
=>
{
expect
(
user
).
to
.
be
.
ok
;
expect
(
user
.
destroyTime
).
to
.
not
.
be
.
ok
;
expect
(
user
.
destroy_time
).
to
.
not
.
be
.
ok
;
});
});
it
(
'supports custom default value'
,
function
()
{
const
ParanoidUser
=
this
.
sequelize
.
define
(
'ParanoidUser'
,
{
username
:
DataTypes
.
STRING
,
deletedAt
:
{
type
:
DataTypes
.
DATE
,
defaultValue
:
new
Date
(
0
)
}
},
{
paranoid
:
true
});
return
ParanoidUser
.
sync
({
force
:
true
}).
then
(()
=>
{
return
ParanoidUser
.
create
({
username
:
'username'
});
}).
then
(
user
=>
{
return
user
.
destroy
();
}).
then
(
user
=>
{
return
user
.
restore
();
}).
then
(
user
=>
{
expect
(
user
.
dataValues
.
deletedAt
.
toISOString
()).
to
.
equal
(
new
Date
(
0
).
toISOString
());
return
ParanoidUser
.
findOne
({
where
:
{
username
:
'username'
}
});
}).
then
(
user
=>
{
expect
(
user
).
to
.
be
.
ok
;
expect
(
user
.
deletedAt
.
toISOString
()).
to
.
equal
(
new
Date
(
0
).
toISOString
());
});
});
});
});
});
});
test/integration/instance/destroy.test.js
View file @
d041e77
This diff is collapsed.
Click to expand it.
test/unit/model/destroy.test.js
View file @
d041e77
...
@@ -35,7 +35,7 @@ describe(Support.getTestDialectTeaser('Model'), () => {
...
@@ -35,7 +35,7 @@ describe(Support.getTestDialectTeaser('Model'), () => {
this
.
stubDelete
.
restore
();
this
.
stubDelete
.
restore
();
});
});
it
(
'can detect complex
e
objects'
,
()
=>
{
it
(
'can detect complex objects'
,
()
=>
{
const
Where
=
function
()
{
this
.
secretValue
=
'1'
;
};
const
Where
=
function
()
{
this
.
secretValue
=
'1'
;
};
expect
(()
=>
{
expect
(()
=>
{
...
...
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