@@ -117,55 +117,75 @@ class DefaultAuthHandler extends DefaultPrismaProxyHandler {
117
117
authDefaultValue : unknown ,
118
118
context : NestedWriteVisitorContext
119
119
) {
120
- if ( fieldInfo . isForeignKey && fieldInfo . relationField && fieldInfo . relationField in data ) {
121
- // if the field is a fk, and the relation field is already set, we should not override it
122
- return ;
123
- }
120
+ if ( fieldInfo . isForeignKey ) {
121
+ // if the field being inspected is a fk field, there are several cases we should not
122
+ // set the default value or should not set directly
124
123
125
- if ( context . field ?. backLink ) {
126
- const modelInfo = getModelInfo ( this . options . modelMeta , model ) ;
127
- const parentModel = modelInfo ?. fields [ context . field . backLink ] ;
128
-
129
- if (
130
- parentModel ?. isDataModel &&
131
- parentModel . foreignKeyMapping &&
132
- Object . keys ( parentModel . foreignKeyMapping ) . includes ( fieldInfo . name )
133
- ) {
134
- // if the field is part of a fk as part of a nested write, then prisma handles setting it
124
+ // if the field is a fk, and the relation field is already set, we should not override it
125
+ if ( fieldInfo . relationField && fieldInfo . relationField in data ) {
135
126
return ;
136
127
}
137
- }
138
128
139
- if ( fieldInfo . isForeignKey && ! isUnsafeMutate ( model , data , this . options . modelMeta ) ) {
140
- // if the field is a fk, and the create payload is not unsafe, we need to translate
141
- // the fk field setting to a `connect` of the corresponding relation field
142
- const relFieldName = fieldInfo . relationField ;
143
- if ( ! relFieldName ) {
144
- throw new Error (
145
- `Field \`${ fieldInfo . name } \` is a foreign key field but no corresponding relation field is found`
129
+ if ( context . field ?. backLink && context . nestingPath . length > 1 ) {
130
+ // if the fk field is in a creation context where its implied by the parent,
131
+ // we should not set the default value, e.g.:
132
+ //
133
+ // ```
134
+ // parent.create({ data: { child: { create: {} } } })
135
+ // ```
136
+ //
137
+ // event if child's fk to parent has a default value, we should not set default
138
+ // value here
139
+
140
+ // fetch parent model from the parent context
141
+ const parentModel = getModelInfo (
142
+ this . options . modelMeta ,
143
+ context . nestingPath [ context . nestingPath . length - 2 ] . model
146
144
) ;
147
- }
148
- const relationField = requireField ( this . options . modelMeta , model , relFieldName ) ;
149
145
150
- // construct a `{ connect: { ... } }` payload
151
- let connect = data [ relationField . name ] ?. connect ;
152
- if ( ! connect ) {
153
- connect = { } ;
154
- data [ relationField . name ] = { connect } ;
146
+ if ( parentModel ) {
147
+ // get the opposite side of the relation for the current create context
148
+ const oppositeRelationField = requireField ( this . options . modelMeta , model , context . field . backLink ) ;
149
+ if ( parentModel . name === oppositeRelationField . type ) {
150
+ // if the opposite side matches the parent model, it means we currently in a creation context
151
+ // that implicitly sets this fk field
152
+ return ;
153
+ }
154
+ }
155
155
}
156
156
157
- // sets the opposite fk field to value `authDefaultValue`
158
- const oppositeFkFieldName = this . getOppositeFkFieldName ( relationField , fieldInfo ) ;
159
- if ( ! oppositeFkFieldName ) {
160
- throw new Error (
161
- `Cannot find opposite foreign key field for \`${ fieldInfo . name } \` in relation field \`${ relFieldName } \``
162
- ) ;
157
+ if ( ! isUnsafeMutate ( model , data , this . options . modelMeta ) ) {
158
+ // if the field is a fk, and the create payload is not unsafe, we need to translate
159
+ // the fk field setting to a `connect` of the corresponding relation field
160
+ const relFieldName = fieldInfo . relationField ;
161
+ if ( ! relFieldName ) {
162
+ throw new Error (
163
+ `Field \`${ fieldInfo . name } \` is a foreign key field but no corresponding relation field is found`
164
+ ) ;
165
+ }
166
+ const relationField = requireField ( this . options . modelMeta , model , relFieldName ) ;
167
+
168
+ // construct a `{ connect: { ... } }` payload
169
+ let connect = data [ relationField . name ] ?. connect ;
170
+ if ( ! connect ) {
171
+ connect = { } ;
172
+ data [ relationField . name ] = { connect } ;
173
+ }
174
+
175
+ // sets the opposite fk field to value `authDefaultValue`
176
+ const oppositeFkFieldName = this . getOppositeFkFieldName ( relationField , fieldInfo ) ;
177
+ if ( ! oppositeFkFieldName ) {
178
+ throw new Error (
179
+ `Cannot find opposite foreign key field for \`${ fieldInfo . name } \` in relation field \`${ relFieldName } \``
180
+ ) ;
181
+ }
182
+ connect [ oppositeFkFieldName ] = authDefaultValue ;
183
+ return ;
163
184
}
164
- connect [ oppositeFkFieldName ] = authDefaultValue ;
165
- } else {
166
- // set default value directly
167
- data [ fieldInfo . name ] = authDefaultValue ;
168
185
}
186
+
187
+ // set default value directly
188
+ data [ fieldInfo . name ] = authDefaultValue ;
169
189
}
170
190
171
191
private getOppositeFkFieldName ( relationField : FieldInfo , fieldInfo : FieldInfo ) {
0 commit comments