@@ -117,55 +117,75 @@ class DefaultAuthHandler extends DefaultPrismaProxyHandler {
117117 authDefaultValue : unknown ,
118118 context : NestedWriteVisitorContext
119119 ) {
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
124123
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 ) {
135126 return ;
136127 }
137- }
138128
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
146144 ) ;
147- }
148- const relationField = requireField ( this . options . modelMeta , model , relFieldName ) ;
149145
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+ }
155155 }
156156
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 ;
163184 }
164- connect [ oppositeFkFieldName ] = authDefaultValue ;
165- } else {
166- // set default value directly
167- data [ fieldInfo . name ] = authDefaultValue ;
168185 }
186+
187+ // set default value directly
188+ data [ fieldInfo . name ] = authDefaultValue ;
169189 }
170190
171191 private getOppositeFkFieldName ( relationField : FieldInfo , fieldInfo : FieldInfo ) {
0 commit comments