所以我目前正在构建一个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? []
答案 0 :(得分:1)
问题很可能是save()
函数没有返回保存的对象这一事实。
最初,我将您的代码更改为:
Post new_post = new Post(description: "testing")
new_post.save()
User user = User.get(springSecurityService.principal.id)
user.addToCreated_posts(new_post).save()
哪个编译了。但是,还有一个问题 - 您不必运行user.addToCreated_posts,而是必须设置new_post的属性creator
,因为您在创建Post域时没有明确指定它可以为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())
我这样做的原因是因为您没有保存用户 - 您正在保存帖子。当您为用户创建帖子时,Grails会在数据库中搜索其中creator_id列设置为您调用该方法的用户的ID的帖子。
另外,我确保您没有从User.groovy中删除以下行:
static hasMany = [createdPosts: Post]
static mappedBy = [createdPosts: "creator"]
你绝对需要以下Post.groovy:
static belongsTo = [creator: User]
这样,Grails知道如何为用户查找帖子。
进行这些更改后,请确保从新的数据库开始 - 对于内存中的H2,这应该自动完成,只要您使用开发环境 - 并重新启动服务器。