diff --git a/orm/db_tables.go b/orm/db_tables.go index cfe415e4..e4c74ace 100644 --- a/orm/db_tables.go +++ b/orm/db_tables.go @@ -186,7 +186,7 @@ func (t *dbTables) getJoinSQL() (join string) { table = jt.mi.table switch { - case jt.fi.fieldType == RelManyToMany || jt.fi.reverse && jt.fi.reverseFieldInfo.fieldType == RelManyToMany: + case jt.fi.fieldType == RelManyToMany || jt.fi.fieldType == RelReverseMany || jt.fi.reverse && jt.fi.reverseFieldInfo.fieldType == RelManyToMany: c1 = jt.fi.mi.fields.pk.column for _, ffi := range jt.mi.fields.fieldsRel { if jt.fi.mi == ffi.relModelInfo { diff --git a/orm/models_test.go b/orm/models_test.go index 2a9962a1..54e5c6ae 100644 --- a/orm/models_test.go +++ b/orm/models_test.go @@ -332,6 +332,24 @@ func NewComment() *Comment { return obj } +type Group struct { + GID string `orm:"pk;column(gid);size(32);unique"` + Name string + Permissions []*Permission `orm:"reverse(many)" json:"-"` +} + +type Permission struct { + ID int `orm:"column(id)"` + Name string + Groups []*Group `orm:"rel(m2m);rel_through(github.com/astaxie/beego/orm.GroupPermissions)"` +} + +type GroupPermissions struct { + ID int `orm:"column(id)"` + Group *Group `orm:"rel(fk)"` + Permission *Permission `orm:"rel(fk)"` +} + var DBARGS = struct { Driver string Source string diff --git a/orm/orm_test.go b/orm/orm_test.go index 1d174fa9..eb872426 100644 --- a/orm/orm_test.go +++ b/orm/orm_test.go @@ -35,6 +35,19 @@ var ( testDateTime = formatDateTime + " -0700" ) +type argAny []interface{} + +// get interface by index from interface slice +func (a argAny) Get(i int, args ...interface{}) (r interface{}) { + if i >= 0 && i < len(a) { + r = a[i] + } + if len(args) > 0 { + r = args[0] + } + return +} + func ValuesCompare(is bool, a interface{}, args ...interface{}) (ok bool, err error) { if len(args) == 0 { return false, fmt.Errorf("miss args") @@ -171,6 +184,9 @@ func TestSyncDb(t *testing.T) { RegisterModel(new(Comment)) RegisterModel(new(UserBig)) RegisterModel(new(PostTags)) + RegisterModel(new(Group)) + RegisterModel(new(Permission)) + RegisterModel(new(GroupPermissions)) err := RunSyncdb("default", true, false) throwFail(t, err) @@ -187,6 +203,9 @@ func TestRegisterModels(t *testing.T) { RegisterModel(new(Comment)) RegisterModel(new(UserBig)) RegisterModel(new(PostTags)) + RegisterModel(new(Group)) + RegisterModel(new(Permission)) + RegisterModel(new(GroupPermissions)) BootStrap() @@ -635,6 +654,45 @@ The program—and web server—godoc processes Go source files to extract docume throwFail(t, err) throwFail(t, AssertIs(id > 0, true)) } + + permissions := []*Permission{ + {Name: "writePosts"}, + {Name: "readComments"}, + {Name: "readPosts"}, + } + + groups := []*Group{ + { + GID: "g1", + Name: "admins", + Permissions: []*Permission{permissions[0], permissions[1], permissions[2]}, + }, + { + GID: "g2", + Name: "users", + Permissions: []*Permission{permissions[1], permissions[2]}, + }, + } + + for _, permission := range permissions { + id, err := dORM.Insert(permission) + throwFail(t, err) + throwFail(t, AssertIs(id > 0, true)) + } + + for _, group := range groups { + id, err := dORM.Insert(group) + throwFail(t, err) + throwFail(t, AssertIs(id > 0, true)) + + num := len(group.Permissions) + if num > 0 { + nums, err := dORM.QueryM2M(group, "permissions").Add(group.Permissions) + throwFailNow(t, err) + throwFailNow(t, AssertIs(nums, num)) + } + } + } func TestCustomField(t *testing.T) { @@ -1398,6 +1456,18 @@ func TestQueryRelate(t *testing.T) { // throwFailNow(t, AssertIs(num, 2)) } +func TestPkManyRelated(t *testing.T) { + permission := &Permission{Name: "readPosts"} + err := dORM.Read(permission, "Name") + throwFailNow(t, err) + + var groups []*Group + qs := dORM.QueryTable("Group") + num, err := qs.Filter("Permissions__Permission", permission.ID).All(&groups) + throwFailNow(t, err) + throwFailNow(t, AssertIs(num, 2)) +} + func TestPrepareInsert(t *testing.T) { qs := dORM.QueryTable("user") i, err := qs.PrepareInsert()