Dynamic finders with Grails many-to-many relationship -
i have 2 domain classes mapped many-to-many relationship. followed instruction of grails documentation, still have problem when processing data on domains. here 2 domain classes:
class user { string name int age string job static hasmany = [groups : group] static belongsto = [org : organization] } class group { string groupname string code static hasmany = [members : user] }
my problems are:
1. above relationship require 1 class hold belongsto "owner" of relationship. in context, user belongs group, not know how put belongsto user class, because standard syntax grails suggest static belongsto = [group] (just specify owner class name), cannot:
- put exist belongsto this: static belongsto = [org : organization, group]
- or define belongsto this: static belongsto = [group]
is below example right:
class book { string title static belongsto = author static hasmany = [authors:author]
static mapping = { authors jointable:[name:"mm_author_books", key:'mm_book_id' ] }
} class author { string name static hasmany = [books:book]
static mapping = { books jointable:[name:"mm_author_books", key:'mm_author_id'] }
}
(ref link: many-to-many link tables in grails (gorm) / hibernate)
mean need specify name of foreign key of join table each class?
- if want find user members of specified group name "abc", how can use dynamicfinder of grails?
thank much
it rare m2m relationships have owning side, i've found odd have specify 1 gorm work correctly. because of this, don't way. create join table domain. things really simple.
class usergroup implements serializable { user user group group boolean equals(other) { if (!(other instanceof usergroup)) { return false } other.user?.id == user?.id && other.group?.id == group?.id } int hashcode() { def builder = new hashcodebuilder() if (user) builder.append(user.id) if (group) builder.append(group.id) builder.tohashcode() } static usergroup get(long userid, long groupid) { find 'from usergroup user.id=:userid , group.id=:groupid', [userid: userid, groupid: groupid] } static usergroup create(user user, group group, boolean flush = false) { new usergroup(user: user, group: group).save(flush: flush, insert: true) } static boolean remove(user user, group group, boolean flush = false) { usergroup instance = usergroup.findbyuserandgroup(user, group) instance ? instance.delete(flush: flush) : false } static void removeall(user user) { executeupdate 'delete usergroup user=:user', [user: user] } static void removeall(group group) { executeupdate 'delete usergroup group=:group', [group: group] } static mapping = { id composite: ['group', 'user'] version false } }
then need create getters in user , group class. won't have user user or group group in either class. there no need map them hasmany/belongsto because create join table, you've done creating usergroup domain.
class user { set<group> getgroups() { usergroup.findallbyuser(this).collect { it.group } set } } class group { set<user> getusers() { usergroup.findallbygroup(this).collect { it.user } set } }
once have these in place can use methods created in usergroup domain and/or can use finders on it...
def usergroupinstance = usergroup.findbyuserandgroup(userinstance, groupinstance) def usergroups = usergroup.findallbyuser(userinstance) def usergroupinstance = usergroup.get(userid, groupid)
you idea. presentation burt beckwith sheds more light on why approach along other great tips performance increases.
Comments
Post a Comment