MCPcopy
hub / github.com/go-gorm/gorm / saveAssociation

Method saveAssociation

association.go:384–606  ·  view source on GitHub ↗
(clear bool, values ...interface{})

Source from the content-addressed store, hash-verified

382}
383
384func (association *Association) saveAssociation(clear bool, values ...interface{}) {
385 var (
386 reflectValue = association.DB.Statement.ReflectValue
387 assignBacks []assignBack // assign association values back to arguments after save
388 )
389
390 appendToRelations := func(source, rv reflect.Value, clear bool) {
391 switch association.Relationship.Type {
392 case schema.HasOne, schema.BelongsTo:
393 switch rv.Kind() {
394 case reflect.Slice, reflect.Array:
395 if rv.Len() > 0 {
396 association.Error = association.Relationship.Field.Set(association.DB.Statement.Context, source, rv.Index(0).Addr().Interface())
397
398 if association.Relationship.Field.FieldType.Kind() == reflect.Struct {
399 assignBacks = append(assignBacks, assignBack{Source: source, Dest: rv.Index(0)})
400 }
401 }
402 case reflect.Struct:
403 if !rv.CanAddr() {
404 association.Error = ErrInvalidValue
405 return
406 }
407 association.Error = association.Relationship.Field.Set(association.DB.Statement.Context, source, rv.Addr().Interface())
408
409 if association.Relationship.Field.FieldType.Kind() == reflect.Struct {
410 assignBacks = append(assignBacks, assignBack{Source: source, Dest: rv})
411 }
412 }
413 case schema.HasMany, schema.Many2Many:
414 elemType := association.Relationship.Field.IndirectFieldType.Elem()
415 oldFieldValue := reflect.Indirect(association.Relationship.Field.ReflectValueOf(association.DB.Statement.Context, source))
416 var fieldValue reflect.Value
417 if clear {
418 fieldValue = reflect.MakeSlice(oldFieldValue.Type(), 0, oldFieldValue.Cap())
419 } else {
420 fieldValue = reflect.MakeSlice(oldFieldValue.Type(), oldFieldValue.Len(), oldFieldValue.Cap())
421 reflect.Copy(fieldValue, oldFieldValue)
422 }
423
424 appendToFieldValues := func(ev reflect.Value) {
425 if ev.Type().AssignableTo(elemType) {
426 fieldValue = reflect.Append(fieldValue, ev)
427 } else if ev.Type().Elem().AssignableTo(elemType) {
428 fieldValue = reflect.Append(fieldValue, ev.Elem())
429 } else {
430 association.Error = fmt.Errorf("unsupported data type: %v for relation %s", ev.Type(), association.Relationship.Name)
431 }
432
433 if elemType.Kind() == reflect.Struct {
434 assignBacks = append(assignBacks, assignBack{Source: source, Dest: ev, Index: fieldValue.Len()})
435 }
436 }
437
438 processMap := func(mapv reflect.Value) {
439 child := reflect.New(association.Relationship.FieldSchema.ModelType)
440
441 switch association.Relationship.Type {

Callers 2

AppendMethod · 0.95
ReplaceMethod · 0.95

Calls 15

LenMethod · 0.80
MakeSliceMethod · 0.80
CapMethod · 0.80
AppendMethod · 0.80
ModelMethod · 0.80
SessionMethod · 0.80
SelectAndOmitColumnsMethod · 0.80
SetMethod · 0.65
TypeMethod · 0.65
NewMethod · 0.65
CreateMethod · 0.65
SelectMethod · 0.65

Tested by

no test coverage detected