Skip to content

Commit 923b80f

Browse files
fix(has-many-dissociator): dissociate relationship when related record is deleted (#429)
1 parent 908af1b commit 923b80f

File tree

2 files changed

+137
-15
lines changed

2 files changed

+137
-15
lines changed

src/services/has-many-dissociator.js

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,21 @@ function HasManyDissociator(model, association, opts, params, data) {
1414
if (error) { return reject(error); }
1515
return resolve();
1616
});
17-
} else {
18-
const updateParams = {};
19-
updateParams[params.associationName] = { $in: documentIds };
20-
21-
model
22-
.findByIdAndUpdate(params.recordId, {
23-
$pull: updateParams,
24-
}, {
25-
new: true,
26-
})
27-
.lean()
28-
.exec((error, record) => {
29-
if (error) { return reject(error); }
30-
return resolve(record);
31-
});
3217
}
18+
const updateParams = {};
19+
updateParams[params.associationName] = { $in: documentIds };
20+
21+
model
22+
.findByIdAndUpdate(params.recordId, {
23+
$pull: updateParams,
24+
}, {
25+
new: true,
26+
})
27+
.lean()
28+
.exec((error, record) => {
29+
if (error) { return reject(error); }
30+
return resolve(record);
31+
});
3332
}));
3433
}
3534

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import mongoose from 'mongoose';
2+
import loadFixture from 'mongoose-fixture-loader';
3+
import Interface from 'forest-express';
4+
import mongooseConnect from '../../utils/mongoose-connect';
5+
import HasManyDissociator from '../../../src/services/has-many-dissociator';
6+
7+
describe('service > has-many-dissociator', () => {
8+
let TreeModel;
9+
let LumberJackModel;
10+
11+
beforeAll(() => {
12+
Interface.Schemas = {
13+
schemas: {
14+
LumberJack: {
15+
name: 'LumberJack',
16+
fields: [
17+
{
18+
field: '_id',
19+
type: 'ObjectId',
20+
},
21+
{
22+
field: 'name',
23+
type: 'String',
24+
},
25+
],
26+
},
27+
Tree: {
28+
name: 'Tree',
29+
fields: [
30+
{
31+
field: '_id',
32+
type: 'ObjectId',
33+
},
34+
{
35+
field: 'name',
36+
type: 'String',
37+
},
38+
{
39+
field: 'owners',
40+
type: ['ObjectId'],
41+
reference: 'LumberJack._id',
42+
},
43+
],
44+
},
45+
},
46+
};
47+
48+
return mongooseConnect()
49+
.then(() => {
50+
const LumberJackSchema = new mongoose.Schema({
51+
_id: { type: 'ObjectId' },
52+
name: { type: String },
53+
});
54+
const TreeSchema = new mongoose.Schema({
55+
id: { type: 'ObjectId' },
56+
name: { type: String },
57+
owners: {
58+
type: ['ObjectId'],
59+
ref: 'LumberJack',
60+
},
61+
});
62+
63+
LumberJackModel = mongoose.model('LumberJack', LumberJackSchema);
64+
TreeModel = mongoose.model('Tree', TreeSchema);
65+
});
66+
});
67+
68+
afterAll(() => mongoose.connection.close());
69+
70+
beforeEach(() => Promise.all([
71+
LumberJackModel.remove({}),
72+
TreeModel.remove({}),
73+
loadFixture(LumberJackModel, [
74+
{
75+
_id: '41224d776a326fb40f000001',
76+
name: 'Kaladin',
77+
},
78+
{
79+
_id: '41224d776a326fb40f000002',
80+
name: 'Adolin Kholin',
81+
},
82+
]),
83+
loadFixture(TreeModel, [
84+
{
85+
_id: '41224d776a326fb40f000003',
86+
name: 'Ashe Tree Lane',
87+
owners: ['41224d776a326fb40f000001', '41224d776a326fb40f000002'],
88+
},
89+
]),
90+
]));
91+
92+
it('should delete the document and the association with option delete=true', async () => {
93+
expect.assertions(3);
94+
await new HasManyDissociator(
95+
TreeModel,
96+
LumberJackModel,
97+
{},
98+
{ delete: true, associationName: 'owners', recordId: '41224d776a326fb40f000003' },
99+
{ data: [{ id: '41224d776a326fb40f000002' }] },
100+
).perform();
101+
const lumberJackDocumentsCount = await LumberJackModel.countDocuments();
102+
const treeDocuments = await TreeModel.find({});
103+
expect(lumberJackDocumentsCount).toStrictEqual(1);
104+
expect(treeDocuments).toHaveLength(1);
105+
expect(treeDocuments[0].owners).toHaveLength(1);
106+
});
107+
108+
it('should delete the association but not the document with delete=false', async () => {
109+
expect.assertions(3);
110+
await new HasManyDissociator(
111+
TreeModel,
112+
LumberJackModel,
113+
{},
114+
{ delete: false, associationName: 'owners', recordId: '41224d776a326fb40f000003' },
115+
{ data: [{ id: '41224d776a326fb40f000001' }] },
116+
).perform();
117+
const lumberJackDocumentsCount = await LumberJackModel.countDocuments();
118+
const treeDocuments = await TreeModel.find({});
119+
expect(lumberJackDocumentsCount).toStrictEqual(2);
120+
expect(treeDocuments).toHaveLength(1);
121+
expect(treeDocuments[0].owners).toHaveLength(1);
122+
});
123+
});

0 commit comments

Comments
 (0)