Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generation of models with recursive associations fail #1242

Open
lloyd-juicelabs opened this issue Dec 6, 2024 · 0 comments
Open

Generation of models with recursive associations fail #1242

lloyd-juicelabs opened this issue Dec 6, 2024 · 0 comments

Comments

@lloyd-juicelabs
Copy link

lloyd-juicelabs commented Dec 6, 2024

Description

When generating models that are recursive, the current pullRelationships method will incorrectly provide an empty result if the value is already in the cache.

Snippet from: https://github.com/go-gorm/gen/blob/master/internal/generate/query.go#L253-L267

for i, relationship := range relationships {
		var childRelations []field.Relation
		varType := strings.TrimLeft(relationship.Field.FieldType.String(), "[]*")
		if !cache[varType] {
			cache[varType] = true
			childRelations = pullRelationShip(cache, append(append(append(append(
				make([]*schema.Relationship, 0, 4),
				relationship.FieldSchema.Relationships.BelongsTo...),
				relationship.FieldSchema.Relationships.HasOne...),
				relationship.FieldSchema.Relationships.HasMany...),
				relationship.FieldSchema.Relationships.Many2Many...),
			)
		}
		result[i] = *field.NewRelationWithType(field.RelationshipType(relationship.Type), relationship.Name, varType, childRelations...)
	}

If the value is in the cache, it will just be populared with an empty result as childRelations is never filled.

For example, generating a model like this:

type User struct {
	Id       string    `gorm:"primaryKey"`
	Posts    []Post    `gorm:"foreignKey:AuthorId"`
	Comments []Comment `gorm:"foreignKey:AuthorId"`
}
type Post struct {
	Id       string `gorm:"primaryKey"`
	AuthorId string
	Author   User      `gorm:"foreignKey:Id"`
	Comments []Comment `gorm:"foreignKey:PostId"`
}
type Comment struct {
	Id       string `gorm:"primaryKey"`
	PostId   string
	Post     Post `gorm:"foreignKey:Id"`
	AuthorId string
	Author   User `gorm:"foreignKey:Id"`
}

pullRelationships will not correctly generate the User.Comments struct as it as already set the cached value to true when processing the User.Posts.Comments struct and will therefore return an empty definition of the relationship into the User object.

_user.Comments = userHasManyComments{
		db: db.Session(&gorm.Session{}),

		RelationField: field.NewRelation("Comments", "tests_test.Comment"),
	}

I have a fix Juice-Labs@85b4d14#diff-76e4b5014eaf9f02f7aaa3e9430cb849f30c063494dd6afb0fc44672cbc763e9 with tests that alter the pullRelationship to build the entire cache before setting up the return values. This ensures that all types are correctly built.

I'm happy to open this change as a PR if you would accept this change or have any suggestions on how it should be changed.

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant