20130515-Grails In Action-3、建模(05小節)

上一節瞭解了1:m的問題,現在解決最棘手的m:n的問題

一般的社交網站上的post都有分類標籤,一個post可以有多個標籤,同樣一個標籤也可以打到多個post上。

比如使用場景如下:

  • 一個用戶可以創建多個標籤
  • 一個帖子可以打上多個標籤,並且每個標籤可能打在多個帖子上

根據這個場景,我們可以看到User和Tag是1:m的關係,Post和Tag是m:n的關係,下面我們就着手建立這兩個關係

1、創建Tag對象

 1 package com.grailsinaction
 2 
 3 class Tag {
 4     
 5     String name
 6     User user
 7 
 8     static constraints = {
 9         name(blank: false)
10     }
11 }

2、首先建立User和Tag的1:m關係

修改User

static hasMany = [ posts : Post, tags : Tag ]

這句代表一個User可以有多個Tag,也可以有多個Post

修改Tag

static belongsTo = [ User ]

這句代表級聯關係,當User刪除了依附在User上的Tag也一併刪除。

3、建立Tag和Post的m:n關係

修改Post

static hasMany = [ tags : Tag ]

修改Tag

static hasMany = [ posts : Post ]

最後定義一個維護端,如:當post實體被刪除時,依附在被刪除的post實體上的tag就沒有存在的意義了,也需要一併刪除

修改Tag

static belongsTo = [ User, Post ]

4、現在User、Profile、Post、Tag之間的關係已經建立好了:

User-Profile:1:1

User-Post:1:m

User-Tag:1:m

Post-Tag:m:n

5、最後測試一下多對多關係的數據操作

打開PostIntegrationTests類,增加測試方法testPostWithTags

 1     @Test
 2     void testPostWithTags() {
 3         def user = new User(userId: 'joe', password: 'secret').save()
 4         def tagGroovy = new Tag(name: 'groovy')
 5         def tagGrails = new Tag(name: 'grails')
 6         user.addToTags(tagGroovy)
 7         user.addToTags(tagGrails)
 8         
 9         def tagNames = user.tags*.name
10         assertEquals([ 'grails', 'groovy'] , tagNames.sort())
11         
12         def groovyPost = new Post(content: "A groovy post")
13         user.addToPosts(groovyPost)
14         groovyPost.addToTags(tagGroovy)
15         assertEquals 1, groovyPost.tags.size()
16         
17         def bothPost = new Post(content: "A groovy and grails post")
18         user.addToPosts(bothPost)
19         bothPost.addToTags(tagGroovy)
20         bothPost.addToTags(tagGrails)
21         assertEquals 2, bothPost.tags.size()
22     }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章