From 3313c11888538af30abed9b168550b426a4af082 Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Wed, 19 Aug 2020 19:02:32 +0800 Subject: [PATCH] Fix embedded struct containing field named ID, close #3286 --- schema/field.go | 8 ++++++++ schema/schema_helper_test.go | 9 +++++++-- schema/schema_test.go | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/schema/field.go b/schema/field.go index 59367399..de937132 100644 --- a/schema/field.go +++ b/schema/field.go @@ -336,6 +336,14 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field { ef.PrimaryKey = true } else { ef.PrimaryKey = false + + if val, ok := ef.TagSettings["AUTOINCREMENT"]; !ok || !utils.CheckTruth(val) { + ef.AutoIncrement = false + } + + if ef.DefaultValue == "" { + ef.HasDefaultValue = false + } } for k, v := range field.TagSettings { diff --git a/schema/schema_helper_test.go b/schema/schema_helper_test.go index f202b487..4e916f84 100644 --- a/schema/schema_helper_test.go +++ b/schema/schema_helper_test.go @@ -49,7 +49,12 @@ func checkSchemaField(t *testing.T, s *schema.Schema, f *schema.Field, fc func(* } } - if parsedField, ok := s.FieldsByName[f.Name]; !ok { + parsedField, ok := s.FieldsByDBName[f.DBName] + if !ok { + parsedField, ok = s.FieldsByName[f.Name] + } + + if !ok { t.Errorf("schema %v failed to look up field with name %v", s, f.Name) } else { tests.AssertObjEqual(t, parsedField, f, "Name", "DBName", "BindNames", "DataType", "PrimaryKey", "AutoIncrement", "Creatable", "Updatable", "Readable", "HasDefaultValue", "DefaultValue", "NotNull", "Unique", "Comment", "Size", "Precision", "Tag", "TagSettings") @@ -62,7 +67,7 @@ func checkSchemaField(t *testing.T, s *schema.Schema, f *schema.Field, fc func(* for _, name := range []string{f.DBName, f.Name} { if name != "" { - if field := s.LookUpField(name); field == nil || parsedField != field { + if field := s.LookUpField(name); field == nil || (field.Name != name && field.DBName != name) { t.Errorf("schema %v failed to look up field with dbname %v", s, f.DBName) } } diff --git a/schema/schema_test.go b/schema/schema_test.go index c0ad3c25..c28812af 100644 --- a/schema/schema_test.go +++ b/schema/schema_test.go @@ -182,3 +182,35 @@ func TestNestedModel(t *testing.T) { }) } } + +func TestEmbeddedStruct(t *testing.T) { + type Company struct { + ID int + Name string + } + + type Corp struct { + ID uint + Base Company `gorm:"embedded;embeddedPrefix:company_"` + } + + cropSchema, err := schema.Parse(&Corp{}, &sync.Map{}, schema.NamingStrategy{}) + + if err != nil { + t.Fatalf("failed to parse embedded struct with primary key, got error %v", err) + } + + fields := []schema.Field{ + {Name: "ID", DBName: "id", BindNames: []string{"ID"}, DataType: schema.Uint, PrimaryKey: true, Size: 64, HasDefaultValue: true, AutoIncrement: true}, + {Name: "ID", DBName: "company_id", BindNames: []string{"Base", "ID"}, DataType: schema.Int, Size: 64, TagSettings: map[string]string{"EMBEDDED": "EMBEDDED", "EMBEDDEDPREFIX": "company_"}}, + {Name: "Name", DBName: "company_name", BindNames: []string{"Base", "Name"}, DataType: schema.String, TagSettings: map[string]string{"EMBEDDED": "EMBEDDED", "EMBEDDEDPREFIX": "company_"}}, + } + + for _, f := range fields { + checkSchemaField(t, cropSchema, &f, func(f *schema.Field) { + f.Creatable = true + f.Updatable = true + f.Readable = true + }) + } +}