Create join table with ReorderModels
This commit is contained in:
		
							parent
							
								
									834cfa2c78
								
							
						
					
					
						commit
						4a01d4c263
					
				| @ -116,20 +116,6 @@ func (m Migrator) AutoMigrate(values ...interface{}) error { | |||||||
| 							} | 							} | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
| 
 |  | ||||||
| 					// create join table
 |  | ||||||
| 					if rel.JoinTable != nil { |  | ||||||
| 						joinValue := reflect.New(rel.JoinTable.ModelType).Interface() |  | ||||||
| 						if !tx.Migrator().HasTable(rel.JoinTable.Table) { |  | ||||||
| 							defer func(table string, joinValue interface{}) { |  | ||||||
| 								errr = tx.Table(table).Migrator().CreateTable(joinValue) |  | ||||||
| 							}(rel.JoinTable.Table, joinValue) |  | ||||||
| 						} else { |  | ||||||
| 							defer func(table string, joinValue interface{}) { |  | ||||||
| 								errr = tx.Table(table).Migrator().AutoMigrate(joinValue) |  | ||||||
| 							}(rel.JoinTable.Table, joinValue) |  | ||||||
| 						} |  | ||||||
| 					} |  | ||||||
| 				} | 				} | ||||||
| 				return nil | 				return nil | ||||||
| 			}); err != nil { | 			}); err != nil { | ||||||
| @ -193,16 +179,6 @@ func (m Migrator) CreateTable(values ...interface{}) error { | |||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 
 |  | ||||||
| 				// create join table
 |  | ||||||
| 				if rel.JoinTable != nil { |  | ||||||
| 					joinValue := reflect.New(rel.JoinTable.ModelType).Interface() |  | ||||||
| 					if !tx.Migrator().HasTable(rel.JoinTable.Table) { |  | ||||||
| 						defer func(table string, joinValue interface{}) { |  | ||||||
| 							errr = tx.Table(table).Migrator().CreateTable(joinValue) |  | ||||||
| 						}(rel.JoinTable.Table, joinValue) |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			for _, chk := range stmt.Schema.ParseCheckConstraints() { | 			for _, chk := range stmt.Schema.ParseCheckConstraints() { | ||||||
| @ -551,9 +527,10 @@ func (m Migrator) ReorderModels(values []interface{}, autoAdd bool) (results []i | |||||||
| 		orderedModelNamesMap          = map[string]bool{} | 		orderedModelNamesMap          = map[string]bool{} | ||||||
| 		valuesMap                     = map[string]Dependency{} | 		valuesMap                     = map[string]Dependency{} | ||||||
| 		insertIntoOrderedList         func(name string) | 		insertIntoOrderedList         func(name string) | ||||||
|  | 		parseDependence               func(value interface{}, addToList bool) | ||||||
| 	) | 	) | ||||||
| 
 | 
 | ||||||
| 	parseDependence := func(value interface{}, addToList bool) { | 	parseDependence = func(value interface{}, addToList bool) { | ||||||
| 		dep := Dependency{ | 		dep := Dependency{ | ||||||
| 			Statement: &gorm.Statement{DB: m.DB, Dest: value}, | 			Statement: &gorm.Statement{DB: m.DB, Dest: value}, | ||||||
| 		} | 		} | ||||||
| @ -564,8 +541,14 @@ func (m Migrator) ReorderModels(values []interface{}, autoAdd bool) (results []i | |||||||
| 				dep.Depends = append(dep.Depends, c.ReferenceSchema) | 				dep.Depends = append(dep.Depends, c.ReferenceSchema) | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if rel.JoinTable != nil && rel.Schema != rel.FieldSchema { | 			if rel.JoinTable != nil { | ||||||
| 				dep.Depends = append(dep.Depends, rel.FieldSchema) | 				if rel.Schema != rel.FieldSchema { | ||||||
|  | 					dep.Depends = append(dep.Depends, rel.FieldSchema) | ||||||
|  | 				} | ||||||
|  | 				// append join value
 | ||||||
|  | 				defer func(joinValue interface{}) { | ||||||
|  | 					parseDependence(joinValue, autoAdd) | ||||||
|  | 				}(reflect.New(rel.JoinTable.ModelType).Interface()) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -4,6 +4,8 @@ import ( | |||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"sort" | 	"sort" | ||||||
| 	"testing" | 	"testing" | ||||||
|  | 
 | ||||||
|  | 	"gorm.io/gorm" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type Blog struct { | type Blog struct { | ||||||
| @ -11,7 +13,7 @@ type Blog struct { | |||||||
| 	Locale     string `gorm:"primary_key"` | 	Locale     string `gorm:"primary_key"` | ||||||
| 	Subject    string | 	Subject    string | ||||||
| 	Body       string | 	Body       string | ||||||
| 	Tags       []Tag `gorm:"many2many:blog_tags;"` | 	Tags       []Tag `gorm:"many2many:blogs_tags;"` | ||||||
| 	SharedTags []Tag `gorm:"many2many:shared_blog_tags;ForeignKey:id;References:id"` | 	SharedTags []Tag `gorm:"many2many:shared_blog_tags;ForeignKey:id;References:id"` | ||||||
| 	LocaleTags []Tag `gorm:"many2many:locale_blog_tags;ForeignKey:id,locale;References:id"` | 	LocaleTags []Tag `gorm:"many2many:locale_blog_tags;ForeignKey:id,locale;References:id"` | ||||||
| } | } | ||||||
| @ -38,7 +40,16 @@ func TestManyToManyWithMultiPrimaryKeys(t *testing.T) { | |||||||
| 		t.Skip("skip sqlite, sqlserver due to it doesn't support multiple primary keys with auto increment") | 		t.Skip("skip sqlite, sqlserver due to it doesn't support multiple primary keys with auto increment") | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	DB.Migrator().DropTable(&Blog{}, &Tag{}, "blog_tags") | 	if name := DB.Dialector.Name(); name == "postgres" { | ||||||
|  | 		stmt := gorm.Statement{DB: DB} | ||||||
|  | 		stmt.Parse(&Blog{}) | ||||||
|  | 		stmt.Schema.LookUpField("ID").Unique = true | ||||||
|  | 		stmt.Parse(&Tag{}) | ||||||
|  | 		stmt.Schema.LookUpField("ID").Unique = true | ||||||
|  | 		// postgers only allow unique constraint matching given keys
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	DB.Migrator().DropTable(&Blog{}, &Tag{}, "blog_tags", "locale_blog_tags", "shared_blog_tags") | ||||||
| 	if err := DB.AutoMigrate(&Blog{}, &Tag{}); err != nil { | 	if err := DB.AutoMigrate(&Blog{}, &Tag{}); err != nil { | ||||||
| 		t.Fatalf("Failed to auto migrate, got error: %v", err) | 		t.Fatalf("Failed to auto migrate, got error: %v", err) | ||||||
| 	} | 	} | ||||||
| @ -127,7 +138,11 @@ func TestManyToManyWithCustomizedForeignKeys(t *testing.T) { | |||||||
| 		t.Skip("skip sqlite, sqlserver due to it doesn't support multiple primary keys with auto increment") | 		t.Skip("skip sqlite, sqlserver due to it doesn't support multiple primary keys with auto increment") | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	DB.Migrator().DropTable(&Blog{}, &Tag{}, "blog_tags") | 	if name := DB.Dialector.Name(); name == "postgres" { | ||||||
|  | 		t.Skip("skip postgers due to it only allow unique constraint matching given keys") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	DB.Migrator().DropTable(&Blog{}, &Tag{}, "blog_tags", "locale_blog_tags", "shared_blog_tags") | ||||||
| 	if err := DB.AutoMigrate(&Blog{}, &Tag{}); err != nil { | 	if err := DB.AutoMigrate(&Blog{}, &Tag{}); err != nil { | ||||||
| 		t.Fatalf("Failed to auto migrate, got error: %v", err) | 		t.Fatalf("Failed to auto migrate, got error: %v", err) | ||||||
| 	} | 	} | ||||||
| @ -248,7 +263,11 @@ func TestManyToManyWithCustomizedForeignKeys2(t *testing.T) { | |||||||
| 		t.Skip("skip sqlite, sqlserver due to it doesn't support multiple primary keys with auto increment") | 		t.Skip("skip sqlite, sqlserver due to it doesn't support multiple primary keys with auto increment") | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	DB.Migrator().DropTable(&Blog{}, &Tag{}, "blog_tags") | 	if name := DB.Dialector.Name(); name == "postgres" { | ||||||
|  | 		t.Skip("skip postgers due to it only allow unique constraint matching given keys") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	DB.Migrator().DropTable(&Blog{}, &Tag{}, "blog_tags", "locale_blog_tags", "shared_blog_tags") | ||||||
| 	if err := DB.AutoMigrate(&Blog{}, &Tag{}); err != nil { | 	if err := DB.AutoMigrate(&Blog{}, &Tag{}); err != nil { | ||||||
| 		t.Fatalf("Failed to auto migrate, got error: %v", err) | 		t.Fatalf("Failed to auto migrate, got error: %v", err) | ||||||
| 	} | 	} | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Jinzhu
						Jinzhu