Grails 中与同一域类的多个 hasMany 关系
我正在使用 Grails,并且我有一个域模型,其中同一域类具有多个 hasMany 属性,如下所示:
static hasMany = [ posts : Post, likes : Post, dislikes : Post ]
我遇到的问题是,当我向帖子列表添加某些内容时,它也会以某种方式使将其放入喜欢和不喜欢的列表中。至少,当我迭代每个列表时,它看起来就是这样。
我认为问题在于我的 Post 域中也存在以下关系:
static belongsTo = [ contributer : Contributer ]
配置这些关系以使我的模型正常工作的最佳方法是什么?有什么建议吗?
@Wayne,
我也尝试使用你的测试,并且它成功通过了。所以,我唯一能想到的是我的 PostController 中的保存方法有问题。我粘贴了下面的相关代码(我正在使用 Spring Security Core 插件,我的 Contributer 类扩展了使用该插件创建的 User 类):
@Secured(['IS_AUTHENTICATED_FULLY'])
def save = {
def props = [title:params.title, post:params.post, category:Category.get(params.category.id)]
def user = Contributer.get(springSecurityService.principal.id)
def postInstance = new Post(props)
postInstance.contributer = user
if (postInstance.save(flush: true)) {
flash.message = "${message(code: 'default.created.message', args: [message(code: 'post.label', default: 'Post'), postInstance.id])}"
redirect(action: "show", id: postInstance.id)
}
else {
render(view: "create", model: [postInstance: postInstance])
}
}
这里有什么突出的地方吗?
I'm using Grails, and I have a domain model with multiple hasMany attributes to the same domain class, which looks like this:
static hasMany = [ posts : Post, likes : Post, dislikes : Post ]
The problem that I'm running into is that when I add something to the posts list, it also somehow makes it into the likes and dislikes lists. At least, that's how it looks when I iterate through each of those lists.
I think that the issue is that I also have the following relationship in my Post domain:
static belongsTo = [ contributer : Contributer ]
What is the best way of going about configuring these relationships to make my model work? Any suggestions?
@Wayne,
I tried using your test as well, and it passed successfully. So, the only thing that I can think of is that there is something wrong with my save method in my PostController. I have pasted the relavent code below (I am using the Spring Security Core plugin, and my Contributer class extends the User class that is created with that plugin):
@Secured(['IS_AUTHENTICATED_FULLY'])
def save = {
def props = [title:params.title, post:params.post, category:Category.get(params.category.id)]
def user = Contributer.get(springSecurityService.principal.id)
def postInstance = new Post(props)
postInstance.contributer = user
if (postInstance.save(flush: true)) {
flash.message = "${message(code: 'default.created.message', args: [message(code: 'post.label', default: 'Post'), postInstance.id])}"
redirect(action: "show", id: postInstance.id)
}
else {
render(view: "create", model: [postInstance: postInstance])
}
}
Is there anything that stands out here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
问题在于,Post 和 Contributor 之间存在一对多关系(帖子有作者,作者有很多帖子),以及 Post 和 Contributor 之间有两个多对多关系(帖子有很多喜欢者,喜欢很多帖子的喜欢者)(帖子有很多不喜欢的人,不喜欢的人不喜欢很多帖子)。 Post 中的
belongsTo
确实解释了该行为,但删除它并不能解决问题,只是会创建不同的问题。最终结果是 GORM 约定将达不到要求,因此您必须告诉 GORM 如何以不同的方式表现或建模。有多种选择,但我首先想到的一个是将 Vote 与 Post 分开建模,以便贡献者
hasMany
likeVotes 和hasMany
dislikeVotesGORM 会将其建模为一张投票表,带有区分喜欢和不喜欢的区分栏;这将使您消除喜欢、不喜欢和撰写的帖子之间的冲突。
然后在 Contributor 中
关系现在就清晰了:
GORM 可以理解这些关系,并且会做出适当的行为。
如果您不喜欢此选项,下一步是为您的数据库结构指定自定义映射,然后使用
mappedBy
来区分各种关系。如果您绝对希望贡献者以三种不同的方式直接与帖子相关,则可以采用这种方法。The problem is that you have a one to many between Post and Contributor (post has an author, author has many posts) as well as two many to many relationships between Post and Contributor (post has many likers, likers like many posts) (post has many dislikers, dislikers dislike many posts). The
belongsTo
in Post does explain the behavior, but removing it will not fix the problem, just create different ones. The end result is that GORM conventions are going to fall short so you have to tell GORM how to behave or model things differntly.There are several options, but the one that jumps to mind is to model Vote separately from Post and make it so that a Contributor
hasMany
likeVotes andhasMany
dislikeVotesGORM will model this as one vote table with a discriminator column to separate likes and dislikes; this will let you eliminate the conflicts between likes, dislikes, and authored posts.
Then in Contributor
The relationships are cleared up now:
GORM can understand these relationships and will behave appropriately.
If you don't like this option, the next step would be to specify custom mappings for your database structure and then use
mappedBy
to differentiate the various relationships. This is the approach to take if you absolutely want to have a Contributor relate directly to Post in three different ways.在域类中使用 staticmappedBy
例如:
在多侧域对象 (Contributer.groovy) 中:
在一侧域对象 (Post.groovy) 中>):
Use static mappedBy in your domain class
For example:
In many side domain object (Contributer.groovy):
In one side domain object (Post.groovy):
不过,多 M:M 的标准方法是使用 joinTable,如 GRAILS-4884 中的建议。
Though, standard way for multi-M:M is to use joinTable, as recommended in GRAILS-4884.
你能展示失败的测试用例吗?我将我认为的情况放入 grails 1.3.7 项目中,测试通过了:
}
Can you show the test case that fails? I put what I think is your case into a grails 1.3.7 project, and the test passes:
}
尝试切换到多对多关系并定义映射域类。在这个映射域类中,您可以指定关系的类型;喜欢、不喜欢或作者。
您可以在这里查看 http://www.grails.org/Many -to-Many+Mapping+without+Hibernate+XML 了解有关多对多映射域类的更多信息。
Try switching to a many-to-many relationship and define a mapping domain class. In this mapping domain class you can then specify the type of relationship; like, dislike, or author.
You can look here http://www.grails.org/Many-to-Many+Mapping+without+Hibernate+XML for further information on a many-to-many mapping domain class.
这应该有效:
This should works: