2011-09-24 65 views
7

我使用Grails,和我有多重的hasMany域模型的屬性相同的域類,它看起來像這樣:多的hasMany關係,同域類Grails的

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

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

我認爲,問題是,我也有我的後域以下關係:

static belongsTo = [ contributer : Contributer ] 

什麼是要去有關配置這些關係,以使我的模型工作的最佳方法?有什麼建議麼?


@Wayne,

我嘗試使用您的測試,以及和它順利通過。所以,我能想到的唯一情況是我的PostController中的保存方法有問題。我粘貼了relavent代碼如下(我使用Spring Security的核心插件,和我的貢獻者類擴展了與該插件創建的用戶類):

@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]) 
} 
} 

有什麼,在這裏脫穎而出?

+0

當您添加後的貢獻者做你該做 'myPost.contributer = myContributer' 或 'myContributer.addToPosts(myPost)'? – fixitagain

+0

@fixitagain,謝謝你的迴應。我已經嘗試了兩種方法,結果相同。 – NickForrer

回答

12

問題是你在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 { 
} 

格姆會模式這是一個投票表用辨別器列來分隔喜歡和不喜歡;這可以讓你消除喜歡,不喜歡和創作的帖子之間的衝突。

然後在投稿

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

的關係正在清理:

  1. 後有很多likeVotes
  2. 後有很多dislikeVotes
  3. 貢獻者有許多likeVotes
  4. 貢獻者有很多人不喜歡票價
  5. 郵政有一個貢獻者
  6. 貢獻者有很多帖子

格姆可以理解這些關係,將表現得體。

如果您不喜歡此選項,下一步將是爲您的數據庫結構指定自定義映射,然後使用mappedBy來區分各種關係。如果您絕對想要以三種不同方式直接將發佈者與帖子關聯起來,則需要採取這種方法。

+0

感謝您的回答!我認爲這對GORM有很大的困惑。非常豐富! – NickForrer

+0

真的很酷的解決方案+1 – fixitagain

1

您能否顯示失敗的測試用例?我把我認爲是你的情況下,進入一個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) 

}

+0

請參閱對問題的編輯。謝謝回答。 –

1

嘗試切換到許多一對多的關係,以及定義的映射域類。在這個映射域類中,你可以指定關係的類型;喜歡,不喜歡,或作者。

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用於對許多一對多映射域類的更多信息。

0

這應該工作:

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'] 
} 
5

使用靜態的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 

    ... 
}