@rws-framework/db 3.11.0 → 3.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/models/core/RWSModel.js +29 -9
- package/dist/models/types/RelationTypes.d.ts +4 -0
- package/dist/models/utils/RelationUtils.js +2 -1
- package/package.json +1 -1
- package/src/models/core/RWSModel.ts +30 -9
- package/src/models/types/RelationTypes.ts +5 -1
- package/src/models/utils/RelationUtils.ts +2 -1
|
@@ -140,18 +140,38 @@ class RWSModel {
|
|
|
140
140
|
const data = {};
|
|
141
141
|
const timeSeriesIds = TimeSeriesUtils_1.TimeSeriesUtils.getTimeSeriesModelFields(this);
|
|
142
142
|
const timeSeriesHydrationFields = [];
|
|
143
|
+
// Get relation metadata to determine how to handle each relation
|
|
144
|
+
const classFields = FieldsHelper_1.FieldsHelper.getAllClassFields(this.constructor);
|
|
145
|
+
const relOneData = await this.getRelationOneMeta(classFields);
|
|
143
146
|
for (const key in this) {
|
|
144
147
|
if (await this.hasRelation(key)) {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
148
|
+
const relationMeta = relOneData[key];
|
|
149
|
+
if (relationMeta) {
|
|
150
|
+
// Use connect on relations that are either:
|
|
151
|
+
// 1. Required (required: true)
|
|
152
|
+
// 2. Have explicitly set cascade options (metaOpts.cascade)
|
|
153
|
+
const hasExplicitCascade = relationMeta.cascade && Object.keys(relationMeta.cascade).length > 0;
|
|
154
|
+
const shouldUseConnect = relationMeta.required || hasExplicitCascade;
|
|
155
|
+
if (shouldUseConnect) {
|
|
156
|
+
// Relations with required=true or explicit cascade → use connect
|
|
157
|
+
if (this[key] === null) {
|
|
158
|
+
data[key] = { disconnect: true };
|
|
159
|
+
}
|
|
160
|
+
else if (this[key] && this[key].id) {
|
|
161
|
+
data[key] = { connect: { id: this[key].id } };
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
// Simple optional relations → use foreign key field directly
|
|
166
|
+
const foreignKeyField = relationMeta.hydrationField;
|
|
167
|
+
if (this[key] === null) {
|
|
168
|
+
data[foreignKeyField] = null;
|
|
169
|
+
}
|
|
170
|
+
else if (this[key] && this[key].id) {
|
|
171
|
+
data[foreignKeyField] = this[key].id;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
153
174
|
}
|
|
154
|
-
// Don't try to set the foreign key directly anymore
|
|
155
175
|
continue;
|
|
156
176
|
}
|
|
157
177
|
if (!(await this.isDbVariable(key))) {
|
|
@@ -12,6 +12,10 @@ export type RelOneMetaType<T extends IRWSModel> = {
|
|
|
12
12
|
model: OpModelType<T>;
|
|
13
13
|
hydrationField: string;
|
|
14
14
|
foreignKey: string;
|
|
15
|
+
cascade?: {
|
|
16
|
+
onDelete?: string;
|
|
17
|
+
onUpdate?: string;
|
|
18
|
+
};
|
|
15
19
|
};
|
|
16
20
|
};
|
|
17
21
|
export type RelManyMetaType<T extends IRWSModel> = {
|
|
@@ -19,7 +19,8 @@ class RelationUtils {
|
|
|
19
19
|
required: resolvedMetadata.required,
|
|
20
20
|
model: resolvedMetadata.relatedTo,
|
|
21
21
|
hydrationField: resolvedMetadata.relationField,
|
|
22
|
-
foreignKey: resolvedMetadata.relatedToField
|
|
22
|
+
foreignKey: resolvedMetadata.relatedToField,
|
|
23
|
+
cascade: resolvedMetadata.cascade
|
|
23
24
|
};
|
|
24
25
|
}
|
|
25
26
|
}
|
package/package.json
CHANGED
|
@@ -179,19 +179,40 @@ class RWSModel<T> implements IModel {
|
|
|
179
179
|
const data: any = {};
|
|
180
180
|
const timeSeriesIds = TimeSeriesUtils.getTimeSeriesModelFields(this);
|
|
181
181
|
const timeSeriesHydrationFields: string[] = [];
|
|
182
|
+
|
|
183
|
+
// Get relation metadata to determine how to handle each relation
|
|
184
|
+
const classFields = FieldsHelper.getAllClassFields(this.constructor);
|
|
185
|
+
const relOneData = await this.getRelationOneMeta(classFields);
|
|
182
186
|
|
|
183
187
|
for (const key in (this as any)) {
|
|
184
|
-
if (await this.hasRelation(key)) {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
188
|
+
if (await this.hasRelation(key)) {
|
|
189
|
+
const relationMeta = relOneData[key];
|
|
190
|
+
|
|
191
|
+
if (relationMeta) {
|
|
192
|
+
// Use connect on relations that are either:
|
|
193
|
+
// 1. Required (required: true)
|
|
194
|
+
// 2. Have explicitly set cascade options (metaOpts.cascade)
|
|
195
|
+
const hasExplicitCascade = relationMeta.cascade && Object.keys(relationMeta.cascade).length > 0;
|
|
196
|
+
const shouldUseConnect = relationMeta.required || hasExplicitCascade;
|
|
197
|
+
|
|
198
|
+
if (shouldUseConnect) {
|
|
199
|
+
// Relations with required=true or explicit cascade → use connect
|
|
200
|
+
if (this[key] === null) {
|
|
201
|
+
data[key] = { disconnect: true };
|
|
202
|
+
} else if (this[key] && this[key].id) {
|
|
203
|
+
data[key] = { connect: { id: this[key].id } };
|
|
204
|
+
}
|
|
205
|
+
} else {
|
|
206
|
+
// Simple optional relations → use foreign key field directly
|
|
207
|
+
const foreignKeyField = relationMeta.hydrationField;
|
|
208
|
+
if (this[key] === null) {
|
|
209
|
+
data[foreignKeyField] = null;
|
|
210
|
+
} else if (this[key] && this[key].id) {
|
|
211
|
+
data[foreignKeyField] = this[key].id;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
192
214
|
}
|
|
193
215
|
|
|
194
|
-
// Don't try to set the foreign key directly anymore
|
|
195
216
|
continue;
|
|
196
217
|
}
|
|
197
218
|
|
|
@@ -23,7 +23,8 @@ export class RelationUtils {
|
|
|
23
23
|
required: resolvedMetadata.required,
|
|
24
24
|
model: resolvedMetadata.relatedTo,
|
|
25
25
|
hydrationField: resolvedMetadata.relationField,
|
|
26
|
-
foreignKey: resolvedMetadata.relatedToField
|
|
26
|
+
foreignKey: resolvedMetadata.relatedToField,
|
|
27
|
+
cascade: resolvedMetadata.cascade
|
|
27
28
|
};
|
|
28
29
|
}
|
|
29
30
|
}
|