diff --git a/schema/relationship.go b/schema/relationship.go index 47b948dc1..35af111f3 100644 --- a/schema/relationship.go +++ b/schema/relationship.go @@ -300,7 +300,7 @@ func (schema *Schema) buildMany2ManyRelation(relation *Relationship, field *Fiel // build references for _, f := range relation.JoinTable.Fields { - if f.Creatable { + if f.Creatable || f.Readable || f.Updatable { // use same data type for foreign keys f.DataType = fieldsMap[f.Name].DataType f.GORMDataType = fieldsMap[f.Name].GORMDataType diff --git a/schema/relationship_test.go b/schema/relationship_test.go index b9279b9f9..7d7fd9c9b 100644 --- a/schema/relationship_test.go +++ b/schema/relationship_test.go @@ -220,6 +220,29 @@ func TestMany2ManyOverrideJoinForeignKey(t *testing.T) { }) } +func TestBuildReadonlyMany2ManyRelation(t *testing.T) { + type Profile struct { + gorm.Model + Name string + UserRefer uint + } + + type User struct { + gorm.Model + Profiles []Profile `gorm:"->;many2many:user_profile;JoinForeignKey:UserReferID;JoinReferences:ProfileRefer"` + Refer uint + } + + checkStructRelation(t, &User{}, Relation{ + Name: "Profiles", Type: schema.Many2Many, Schema: "User", FieldSchema: "Profile", + JoinTable: JoinTable{Name: "user_profile", Table: "user_profile"}, + References: []Reference{ + {"ID", "User", "UserReferID", "user_profile", "", true}, + {"ID", "Profile", "ProfileRefer", "user_profile", "", false}, + }, + }) +} + func TestMany2ManyWithMultiPrimaryKeys(t *testing.T) { type Tag struct { ID uint `gorm:"primary_key"` diff --git a/schema/schema.go b/schema/schema.go index ea81d6832..c3d3f6e0b 100644 --- a/schema/schema.go +++ b/schema/schema.go @@ -133,7 +133,7 @@ func Parse(dest interface{}, cacheStore *sync.Map, namer Namer) (*Schema, error) if field.DBName != "" { // nonexistence or shortest path or first appear prioritized if has permission - if v, ok := schema.FieldsByDBName[field.DBName]; !ok || (field.Creatable && len(field.BindNames) < len(v.BindNames)) { + if v, ok := schema.FieldsByDBName[field.DBName]; !ok || ((field.Creatable || field.Updatable || field.Readable) && len(field.BindNames) < len(v.BindNames)) { if _, ok := schema.FieldsByDBName[field.DBName]; !ok { schema.DBNames = append(schema.DBNames, field.DBName) } @@ -219,7 +219,7 @@ func Parse(dest interface{}, cacheStore *sync.Map, namer Namer) (*Schema, error) if _, loaded := cacheStore.LoadOrStore(modelType, schema); !loaded { if _, embedded := schema.cacheStore.Load(embeddedCacheKey); !embedded { for _, field := range schema.Fields { - if field.DataType == "" && field.Creatable { + if field.DataType == "" && (field.Creatable || field.Updatable || field.Readable) { if schema.parseRelation(field); schema.err != nil { return schema, schema.err }