簡體   English   中英

與Grails中的同一域類有多個hasMany關系

[英]Multiple hasMany relationships to same domain class in Grails

我正在使用Grails,並且我有一個具有多個hasMany屬性的域模型到同一個域類,如下所示:

static hasMany = [ posts : Post, likes : Post, dislikes : Post ]

我遇到的問題是,當我在帖子列表中添加內容時,它也會以某種方式將其變成喜歡和不喜歡的列表。 至少,當我遍歷每個列表時,它就是這樣的樣子。

我認為問題是我在Post域中也有以下關系:

static belongsTo = [ contributer : Contributer ]

配置這些關系以使我的模型工作的最佳方法是什么? 有什么建議?


@Wayne,

我也試過使用你的測試,它成功通過了。 所以,我唯一能想到的是我的PostController中的save方法有問題。 我已粘貼下面的相關代碼(我正在使用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])
}
}

有什么突出的嗎?

問題是你在Post和Contributor之間有一對多(帖子有作者,作者有很多帖子)以及Post和Contributor之間有兩對多關系(帖子有很多喜歡的帖子,像很多帖子一樣)(帖子)有很多不喜歡的人,不喜歡很多帖子。 Post中的belongsTo確實解釋了行為,但刪除它不會解決問題,只需創建不同的問題。 最終結果是GORM約定將會失敗,因此您必須告訴GORM如何對事物進行不同的行為或建模。

有幾個選項,而是跳轉到心中的一個是從后分別模擬投票,並讓這個貢獻者hasMany likeVotes和hasMany dislikeVotes

class Vote {

   // for illustration here, you need to think about the 
   // cascading behavior that makes sense and model it if you decide 
   // to go this route. 
  belongsTo = [post, contributor] 

}

class LikeVote extends Vote {
}

class DislikeVote extends Vote {
}

GORM會將此模型建模為一個帶有鑒別器列的投票表,以區分好惡; 這樣可以消除喜歡,不喜歡和創作帖子之間的沖突。

然后在貢獻者

 hasMany = [likes:LikeVote, dislikes:DislikeVote, posts:Post]

現在關系清理了:

  1. 郵政有許多喜歡投票
  2. 郵政有很多不喜歡的投票
  3. 貢獻者有很多喜歡投票
  4. 貢獻者有很多不喜歡的投票
  5. 郵政有一個貢獻者
  6. 貢獻者有很多帖子

GORM可以理解這些關系並且行為恰當。

如果您不喜歡此選項,則下一步是為數據庫結構指定自定義映射,然后使用mappedBy區分各種關系。 如果您絕對希望讓投稿人以三種不同的方式直接與Post相關,那么這就是您要采取的方法。

在域類中使用static mappedBy

例如:

在許多側域對象( Contributer.groovy )中:

static hasMany = [ posts : Post, likes : Post, dislikes : Post ]
static mappedBy = [posts: "postsContributer", likes: "likesContributer", dislikes: "dislikesContributer"]

在一個側域對象( Post.groovy ):

Class Post {

       static belongsTo = [ contributer : Contributer ]

       Contributer postsContributer
       Contributer likesContributer
       Contributer dislikesContributer

   ... 
}

雖然,多M:M的標准方法是使用joinTable ,如GRAILS-4884中所推薦的那樣

這應該有效:

static hasMany = [ posts : Post, likes : Post, dislikes : Post ]

static mapping = {
    posts joinTable: [name: 'contributor_posts']
    likes joinTable: [name: 'contributor_likes']
    dislikes joinTable: [name: 'contributor_dislikes']
}

你能證明測試用例失敗了嗎? 我把我認為你的情況放到了grails 1.3.7項目中,測試通過:

class Post {
    String text ="postal"
    static belongsTo = [ contributor : Contributor ]
    static constraints = { }
}
class Contributor {
    String name = "Big C"
    static hasMany = [ posts : Post, likes : Post, dislikes : Post ]
    static constraints = { }
}

// integration test
void testMultipleRel() {
    Contributor c = new Contributor().save()
    assertNotNull c

    Post p1 = new Post(text:"neutral")
    Post p2 = new Post(text:"like")
    Post p3 = new Post(text:"dislike")
    [p1,p2,p3].each {c.addToPosts(it).save()}
    assertNotNull p1
    assertNotNull p2
    assertNotNull p3

    assertNull c.likes
    assertNull c.dislikes

    c.addToLikes(p2)
    c.addToDislikes(p3)

    assertEquals ([p1, p2, p3] as Set, c.posts as Set)
    assertEquals ([p2]         as Set, c.likes as Set)
    assertEquals ([p3]         as Set, c.dislikes as Set)

}

嘗試切換到多對多關系並定義映射域類。 在此映射域類中,您可以指定關系類型; 喜歡,不喜歡或作者。

class Contributor {
    static hasMany = [contributorPosts:ContributorPost]
}

class ContributorPost {
    Post post
    Contributor contributor
    Boolean like
    Boolean dislike
    Boolean author
}

class Post {
    static hasMany = [contributorPosts:ContributorPost]
}

您可以在這里查看http://www.grails.org/Many-to-Many+Mapping+without+Hibernate+XML,以獲取有關多對多映射域類的更多信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM