Describe the feature
Im often missing smart selecting fields in relations, so I don't have to load the whole model. This would allow for something like:
type Post struct {
gorm.Model
Title string
Content string
UserID uint
}
type PostTitle struct {
ID int
Title string
UserID uint
}
type User struct {
gorm.Model
PostTitles []PostTitle `gorm:"foreignKey:UserID"` // hint somehow that this is not a model
// ... many more fields
}
Motivation
This would allow issuing tailored queries without overhead and manual mapping. For example, one could create a separate type solely for querying a user and his post titles.
type UserWithPosts struct {
ID int
PostTitles []PostTItle `gorm:"foreignKey:UserID"`
}
Related Issues
Currently relations in smart selected fields "kind of" work (https://github.com/go-gorm/gorm/issues/4015). I'd honestly would not regard this issue as closed.
Implementation
I've skimmed through schema and preload.go and it seems to me that this is not easy to implement.
Furthermore, I've looked at GetIdentityFieldValuesMap, to find out why it doesn't always work the other way round.
The root of the problem is that Relationships are genrated only for first-class models, which means they can't be used for smart selected fields (from now on SSF) on neither side of the relation.
Luckily, we can load SSF by easily squeezing a Model() clause into the genrated preload query (I got it working).
Now we just have to identify the correct tables (what if we have an SSF to SSF join?) and access the foreign keys in those derived structs (because Relationship.Field.Set won't work).
Does an SSF struct always have to be a subtype of the model? Of course, but embedded fields (like gorm.Model) should to be transparent. This would also resolve the linked issue.
One way of correctly accessing fields would be generating seprarate Schemas for SSFs but with table names of their models and injected schemas for their SSF relations. They could be generated on first use and stored in DB.cacheStore, like first-class models. However, this means that each SSF query with a new type generates a new schema (which makes them less lightweight).
How to identify table names for SSF relations?. SSF without relations works only because a Statement has both a Model and a Dest field and the model is explicitly set through a Model() call. Go really lacks java-like annotaions which allow types to be passed in.
* One could simply set them with struct tags, but this would not adhere to ORM principles.
* One could pass model types in a Preload() call, but what to do with clause.Associations and nested paths?
* One could create a speical interface for SSF structs which returns the full Model, but this would make them harder to use.
I have some spare time left for implementing this kind of desired behaviour. Which implementations would seem reasonable?
Comment From: jinzhu
Should works in latest version.