forked from mirror/gorm
Fix self-referential belongs to constraint (#4801)
* create tests for self-ref has one migration * add relation equality check to avoid skipping self-referential schemas * remove drop table error check
This commit is contained in:
parent
4c8810a848
commit
d9d5c4dce0
|
@ -519,7 +519,7 @@ func (rel *Relationship) ParseConstraint() *Constraint {
|
||||||
|
|
||||||
if rel.Type == BelongsTo {
|
if rel.Type == BelongsTo {
|
||||||
for _, r := range rel.FieldSchema.Relationships.Relations {
|
for _, r := range rel.FieldSchema.Relationships.Relations {
|
||||||
if r.FieldSchema == rel.Schema && len(rel.References) == len(r.References) {
|
if r != rel && r.FieldSchema == rel.Schema && len(rel.References) == len(r.References) {
|
||||||
matched := true
|
matched := true
|
||||||
for idx, ref := range r.References {
|
for idx, ref := range r.References {
|
||||||
if !(rel.References[idx].PrimaryKey == ref.PrimaryKey && rel.References[idx].ForeignKey == ref.ForeignKey &&
|
if !(rel.References[idx].PrimaryKey == ref.PrimaryKey && rel.References[idx].ForeignKey == ref.ForeignKey &&
|
||||||
|
|
|
@ -93,6 +93,21 @@ func TestBelongsToWithOnlyReferences2(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSelfReferentialBelongsTo(t *testing.T) {
|
||||||
|
type User struct {
|
||||||
|
ID int32 `gorm:"primaryKey"`
|
||||||
|
Name string
|
||||||
|
CreatorID *int32
|
||||||
|
Creator *User
|
||||||
|
}
|
||||||
|
|
||||||
|
checkStructRelation(t, &User{}, Relation{
|
||||||
|
Name: "Creator", Type: schema.BelongsTo, Schema: "User", FieldSchema: "User",
|
||||||
|
References: []Reference{{"ID", "User", "CreatorID", "User", "", false}},
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func TestSelfReferentialBelongsToOverrideReferences(t *testing.T) {
|
func TestSelfReferentialBelongsToOverrideReferences(t *testing.T) {
|
||||||
type User struct {
|
type User struct {
|
||||||
ID int32 `gorm:"primaryKey"`
|
ID int32 `gorm:"primaryKey"`
|
||||||
|
|
|
@ -54,6 +54,25 @@ func TestMigrate(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAutoMigrateSelfReferential(t *testing.T) {
|
||||||
|
type MigratePerson struct {
|
||||||
|
ID uint
|
||||||
|
Name string
|
||||||
|
ManagerID *uint
|
||||||
|
Manager *MigratePerson
|
||||||
|
}
|
||||||
|
|
||||||
|
DB.Migrator().DropTable(&MigratePerson{})
|
||||||
|
|
||||||
|
if err := DB.AutoMigrate(&MigratePerson{}); err != nil {
|
||||||
|
t.Fatalf("Failed to auto migrate, but got error %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !DB.Migrator().HasConstraint("migrate_people", "fk_migrate_people_manager") {
|
||||||
|
t.Fatalf("Failed to find has one constraint between people and managers")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestSmartMigrateColumn(t *testing.T) {
|
func TestSmartMigrateColumn(t *testing.T) {
|
||||||
fullSupported := map[string]bool{"mysql": true, "postgres": true}[DB.Dialector.Name()]
|
fullSupported := map[string]bool{"mysql": true, "postgres": true}[DB.Dialector.Name()]
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue