protoc-gen-gorm
protoc-gen-gorm copied to clipboard
association_autoupdate does not work with DefaultStrictUpdate
The generated default server uses DefaultStrictUpdate. This deletes all children of the item you are trying to patch.
e.g
filterProjects := ProjectORM{}
if ormObj.Id == 0 {
return nil, errors1.EmptyIdError
}
filterProjects.ClientId = new(uint32)
*filterProjects.ClientId = ormObj.Id
if err = db.Where(filterProjects).Delete(ProjectORM{}).Error; err != nil {
return nil, err
}
I do not understand the thinking behind this.
This means that https://github.com/infobloxopen/protoc-gen-gorm/blob/master/README.md#customization trying to control the behaviour of associations wont work as you have no control over whether children are deleted.
When using
[(gorm.field).has_many = {
association_autoupdate: false
}]
children should not be effected or in my opinion better yet, children should never be effected as this is a un-foreseen side effect and this logic should be left to the implementer to control
Also please note this only "deletes children" when using deleted_at for soft delete.
Actually the delete happens even without deleted_at I'm not sure why it deletes some models and not others though
Handling associations is I think the trickiest part of this tool, and it could certainly be better. To explain the general reasoning behind the current behavior (which may not be playing well with the Gorm settings, I believe those tags were brought into this package later) Ex: if you have an object with child objects
type Foo struct {
ID int
Name string
Children []Bar
}
type Bar struct {
ID int
FooID int
Name string
}
and you update the object like so
myFoo := Foo{
Name: "test",
Children: []Bar{{Name: "abc"}, {Name: "def"}},
}
DefaultCreateFoo(ctx, &myFoo, db)
myFoo.Children = []Bar{{Name: "xyz"}, {Name: "def"}}
DefaultUpdateFoo(ctx, &myFoo, db)
The behavior I considered to be most intuitive was that the children would now be {ID: <autogenerated>, Name: "xyz"} and {ID: <autogenerated>, Name: "def"}. Without clearing the old associations, the {ID: <autogenerated>, Name: "abc"} would also still be a child object and returned by a Read. This ties a bit into #93 which I opened a long time ago for an improvement I'd like to make that leaves/updates children objects with specified IDs instead of autogenerated ones.
If you were focused on PATCH specifically, it would be good if associations that are not included in the request are completely untouched, as opposed to the PUT which may have to touch everything (I think right now for PATCH it's just merging the new and DB objects and then doing a PUT, which for some use cases can cause other problems, too). We may want to address this and may have to split up the generated code for PUT and PATCH more to resolve this case.
I'm open to discussion on this (and @dkukharau's input). Skipping that association overwrite if the GORM flag is false seems like a reasonable change to me, but I still think that it is more intuitive to drop old associations during update (PUTs or PATCHes on those fields) by default.
Thanks for the response. I can see your thinking but I find that in some cases you might not have the children. In this case they will be wiped.
I presume you would not be up for just getting rid of this and leaving this kinda logic to he implementor.
There are a few options for associations that would need to be covered, I feel as though to implement them all would mean this would be trying to do too much.
Maybe a simple solution would to be able to turn this functionality on and off as part of a (gorm.server).autogen option. What do you think?