Grails:创建多对多对多关系?
Grails: creating a many-to-many-to-many relationship?
所以我目前正在构建一个 Grails 应用程序,我正在尝试允许用户创建帖子,并且这些帖子也有评论。
我要创建的关联类似于:
一个用户可以有 0 到多个帖子,并且
帖子可以有 0 到很多评论
我尝试使用我的域 类 进行如下设置:
class User implements Serializable{
static hasMany = [created_posts: Post]
String username
String password
}
class Post {
static hasMany = [comments: Comment]
String description
}
class Comment {
String comment_body
static belongsTo = [post: Post]
}
我也尝试使用 mappedBy 属性,如下所示:
class User implements Serializable{
static hasMany = [created_posts: Post]
static mappedBy = [created_posts: 'creator']
String username
String password
}
class Post {
static hasMany = [comments: Comment]
static belongsTo = [creator: User]
String description
}
class Comment {
String comment_body
static belongsTo = [post: Post]
}
但是还是不行。我用来创建它的代码如下:
Post new_post = new Post(description: "testing").save()
User user = User.get(springSecurityService.principal.id)
user.addToCreated_posts(new_post).save()
不幸的是,Grails 似乎无法执行最后一行,有时它根本无法编译,给出一个 :bootRun 错误。
我不确定如何在用户、帖子和评论之间创建正确的关联。欢迎任何帮助,不胜感激!
编辑:我当前的代码:(编译,但不保存到用户集)
class User implements Serializable{
static hasMany = [createdPosts: Post]
static mappedBy = [createdPosts: 'creator']
String username
String password
}
class Post {
static hasMany = [comments: Comment]
static belongsTo = [creator: User]
String description
static constraints = { creator nullable: true }
}
class Comment {
String comment_body
static belongsTo = [post: Post]
}
我在控制器中使用的代码:
User user = User.get(springSecurityService.principal.id)
Post new_post = new Post(description: "testing description", creator: user).save()
user.save()
System.out.println("post saved to user? " + user.getCreatedPosts())
输出为:
post saved to user? []
问题很可能是 save()
函数没有 return 保存的对象。
最初,我将您的代码更改为:
Post new_post = new Post(description: "testing")
new_post.save()
User user = User.get(springSecurityService.principal.id)
user.addToCreated_posts(new_post).save()
哪个编译了。但是,还有一个问题 - 您必须设置 new_post 的 运行 user.addToCreated_posts 而不是 运行 creator
,因为您没有明确地设置在您创建 Post 域 class 时指定它可以为 null。因此,对 save()
的调用将默默地失败。
如果将代码更改为:
User user = User.get(springSecurityService.principal.id)
Post new_post = new Post(description: "testing", creator: user)
new_post.save()
您的代码应该可以工作。
将所有对 save()
的调用替换为 save(failOnError: true)
可能也是一个好主意,这样当保存失败时,就会抛出异常。您可以捕获此异常,并从异常中提取错误消息。通常,错误消息与域对象验证失败有关。
这是在 Grails 3.2.7 上测试的,使用 H2(与 Grails 一起打包的默认内存数据库)。
编辑这是基于对问题所做的更新的更新片段。
你是运行:
User user = User.get(springSecurityService.principal.id)
Post new_post = new Post(description: "testing description", creator: user).save()
user.save()
System.out.println("post saved to user? " + user.getCreatedPosts())
我会将其更改为:
User user = User.get(springSecurityService.principal.id)
Post new_post = new Post(description: "testing description", creator: user)
new_post.save(failOnError: true)
System.out.println("post saved to user? " + user.getCreatedPosts())
我这样做的原因是你不是在拯救用户——你是在拯救 post。当您为用户创建 posts 时,Grails 会在数据库中搜索 posts,其中 creator_id 列设置为您从中调用该方法的用户的 ID。
此外,我会确保您没有从 User.groovy 中删除以下行:
static hasMany = [createdPosts: Post]
static mappedBy = [createdPosts: "creator"]
您绝对需要Post.groovy以下内容:
static belongsTo = [creator: User]
这样,Grails 就知道应该如何为用户查找 Posts。
进行这些更改后,请确保从新的数据库开始 - 对于内存中的 H2,只要您使用的是开发环境,这应该会自动完成 - 并重新启动服务器。
所以我目前正在构建一个 Grails 应用程序,我正在尝试允许用户创建帖子,并且这些帖子也有评论。
我要创建的关联类似于:
一个用户可以有 0 到多个帖子,并且 帖子可以有 0 到很多评论
我尝试使用我的域 类 进行如下设置:
class User implements Serializable{
static hasMany = [created_posts: Post]
String username
String password
}
class Post {
static hasMany = [comments: Comment]
String description
}
class Comment {
String comment_body
static belongsTo = [post: Post]
}
我也尝试使用 mappedBy 属性,如下所示:
class User implements Serializable{
static hasMany = [created_posts: Post]
static mappedBy = [created_posts: 'creator']
String username
String password
}
class Post {
static hasMany = [comments: Comment]
static belongsTo = [creator: User]
String description
}
class Comment {
String comment_body
static belongsTo = [post: Post]
}
但是还是不行。我用来创建它的代码如下:
Post new_post = new Post(description: "testing").save()
User user = User.get(springSecurityService.principal.id)
user.addToCreated_posts(new_post).save()
不幸的是,Grails 似乎无法执行最后一行,有时它根本无法编译,给出一个 :bootRun 错误。
我不确定如何在用户、帖子和评论之间创建正确的关联。欢迎任何帮助,不胜感激!
编辑:我当前的代码:(编译,但不保存到用户集)
class User implements Serializable{
static hasMany = [createdPosts: Post]
static mappedBy = [createdPosts: 'creator']
String username
String password
}
class Post {
static hasMany = [comments: Comment]
static belongsTo = [creator: User]
String description
static constraints = { creator nullable: true }
}
class Comment {
String comment_body
static belongsTo = [post: Post]
}
我在控制器中使用的代码:
User user = User.get(springSecurityService.principal.id)
Post new_post = new Post(description: "testing description", creator: user).save()
user.save()
System.out.println("post saved to user? " + user.getCreatedPosts())
输出为:
post saved to user? []
问题很可能是 save()
函数没有 return 保存的对象。
最初,我将您的代码更改为:
Post new_post = new Post(description: "testing")
new_post.save()
User user = User.get(springSecurityService.principal.id)
user.addToCreated_posts(new_post).save()
哪个编译了。但是,还有一个问题 - 您必须设置 new_post 的 运行 user.addToCreated_posts 而不是 运行 creator
,因为您没有明确地设置在您创建 Post 域 class 时指定它可以为 null。因此,对 save()
的调用将默默地失败。
如果将代码更改为:
User user = User.get(springSecurityService.principal.id)
Post new_post = new Post(description: "testing", creator: user)
new_post.save()
您的代码应该可以工作。
将所有对 save()
的调用替换为 save(failOnError: true)
可能也是一个好主意,这样当保存失败时,就会抛出异常。您可以捕获此异常,并从异常中提取错误消息。通常,错误消息与域对象验证失败有关。
这是在 Grails 3.2.7 上测试的,使用 H2(与 Grails 一起打包的默认内存数据库)。
编辑这是基于对问题所做的更新的更新片段。
你是运行:
User user = User.get(springSecurityService.principal.id)
Post new_post = new Post(description: "testing description", creator: user).save()
user.save()
System.out.println("post saved to user? " + user.getCreatedPosts())
我会将其更改为:
User user = User.get(springSecurityService.principal.id)
Post new_post = new Post(description: "testing description", creator: user)
new_post.save(failOnError: true)
System.out.println("post saved to user? " + user.getCreatedPosts())
我这样做的原因是你不是在拯救用户——你是在拯救 post。当您为用户创建 posts 时,Grails 会在数据库中搜索 posts,其中 creator_id 列设置为您从中调用该方法的用户的 ID。
此外,我会确保您没有从 User.groovy 中删除以下行:
static hasMany = [createdPosts: Post]
static mappedBy = [createdPosts: "creator"]
您绝对需要Post.groovy以下内容:
static belongsTo = [creator: User]
这样,Grails 就知道应该如何为用户查找 Posts。
进行这些更改后,请确保从新的数据库开始 - 对于内存中的 H2,只要您使用的是开发环境,这应该会自动完成 - 并重新启动服务器。