gpt4 book ai didi

grails - Grails的继承以及一对多和多对多关系的冲突

转载 作者:行者123 更新时间:2023-12-02 14:52:10 24 4
gpt4 key购买 nike

我通过尝试创建简单的Twitter副本来学习grails。我目前正在尝试纳入关注者和群组。我最初想出了一个非常基本的数据库结构,但在实现它方面却没有运气。关系的设计如下:

    Person:
has many: Groups, Tweets, (Person as followers through User2Person)
Group:
has many: (Person as followers through User2Person)
belongs to: Person as owner
User2Person:
belongs to: (Person or Group)
belongs to: Person

基本上,我希望Person和Group成为User的实例,然后创建一个将User映射到Person的表。这样,仅一个表被创建/用于Group2Person和Person2Person之间的关系。

详细信息:组是由人员创建的,因此它应该具有“所有者”(person_id)。它还有许多关注者(即成员)。组不能跟随其他组,但是一个人可以跟随另一个人或一个组。

下面是我如何在grails中实现此功能:

用户
    abstract class User {
static hasMany = [followers: Person]
static mappedBy = [followers: "followed"]
String name
Date dateCreated
Date lastUpdated

static constraints = {
name shared: "mustFill", size: 3..20
}
}


    class Person extends User {
static belongsTo = [followed: User]
static hasMany = [tweets: Tweet, groups: Group]
static mappedBy = [groups: "owner"]
String username
String email

static constraints = {
username shared: "mustFill", unique: true, size: 4..15
email shared: "mustFill", email: true
}

static mapping = {
tweets sort: 'dateCreated', order: 'desc'
}

}


    class Group extends User {
Person owner
String description

def getTweets() {
return followers.tweets.flatten()
}

static transients = {
tweets
}
}

鸣叫(以防万一?)
    class Tweet {
static belongsTo = [author: Person]
String text
Date dateCreated

static constraints = {
text shared: "mustFill", maxSize: 140
}
}

运行cmd grails schema-export时,出现以下错误:“|错误加载插件管理器时出错:域类[tweeter.Group]和[tweeter.Person类]不能以多对多的关系相互拥有。包含相互引用的belongsTo定义。(使用--stacktrace查看完整的跟踪)”

最佳答案

我能够使数据库创建几乎正确的架构。不幸的是,使用了User2Person(又称关注者)联接表的主键(user_id,person_id)。这意味着我不能有两个记录,例如:(1、2)和(2、1)(例如,两个用户彼此关注)。以下是更新的类(commit):

用户

    class User {
static belongsTo = Person
static hasMany = [followers: Person]
String name
Date dateCreated
Date lastUpdated

static constraints = {
name shared: "mustFill", size: 3..20
}
}


    class Person extends User {
static hasMany = [tweets: Tweet, groups: Group, follows: User]
static mappedBy = [tweets: "author", groups: "owner"]
String username
String email

static constraints = {
username shared: "mustFill", unique: true, size: 4..15
email shared: "mustFill", email: true
}

static mapping = {
tweets sort: 'dateCreated', order: 'desc'
}

}

模式中的关注者表如下所示:
    create table user_follows (
user_id bigint,
follows__id bigint,
primary_key(user_id, follows__id)
)

我在网上搜索了有关更改联接表主键的信息。我能找到的最好的方法是使用类似以下的代码:
    static mappedBy = { followers joinTable: [name:"someName", ...] }

不幸的是,我很难找到有关joinTable映射的好的文档,并且大多数资料似乎都表明不可能轻易更改连接表的主键。然后,我决定按照本指南使用单独的域类来定义联接表:没有Hibernate XML的多对多映射。以下是最终更新的代码( commit):

用户
    class User {
static belongsTo = Person
static hasMany = [people: UserFollower]
static mappedBy = [people: "followed"]
String name
Date dateCreated
Date lastUpdated

static constraints = {
name shared: "mustFill", size: 3..20
}

static transients = {
followers
}

def getFollowers() {
return people.collect { it.follower }
}

void addToFollowers(Person person) {
UserFollower.link(this, person)
}

void removeFromFollowers(Person person) {
UserFollower.unlink(this, person)
}
}


    class Person extends User {
static hasMany = [tweets: Tweet, groups: Group, users: UserFollower]
static mappedBy = [tweets: "author", groups: "owner", users:"follower"]
String username
String email

static constraints = {
username shared: "mustFill", unique: true, size: 4..15
email shared: "mustFill", email: true
}

static mapping = {
tweets sort: 'dateCreated', order: 'desc'
}

static transients = {
follows
}

def getFollows() {
return users.collect { it.followed }
}

void addToFollows(User user) {
UserFollower.link(user, this)
}

void removeFromFollows(User user) {
UserFollower.unlink(user, this)
}

}

用户关注
    class UserFollower {
User followed
Person follower

static constraints = {
followed nullable: false
follower nullable: false
}

static void link(User user, Person person) {
UserFollower f = UserFollower.findByFollowedAndFollower(user, person)
if(!f) {
f = new UserFollower()
user.addToPeople(f)
person.addToUsers(f)
f.save()
}
}

static void unlink(User user, Person person) {
UserFollower f = UserFollower.findByFollowedAndFollower(user, person)
if(f) {
f = new UserFollower()
user.removeFromPeople(f)
person.removeFromUsers(f)
f.delete()
}
}
}

关于grails - Grails的继承以及一对多和多对多关系的冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24706056/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com