Finally finished this chapter, a lot of harvest ah.
And Django have similar, also have different.
User.groovy:
Packagecom.grailsinactionclassUser {string loginId string password Date dateCreatedStaticHasOne =[Profile:profile]StaticHasmany =[Posts:post, Tags:tag, Following:user]StaticMapping = {posts sort: ' dateCreated '} Staticconstraints ={loginId Size:3..20, Unique:true, Nullable:falsePassword Size:6..8, Nullable:false, validator: {passwd, user--passwd! =User.loginid} profile Nullable:true }}
Profile.groovy:
Packagecom.grailsinactionclassProfile {User Userbyte[] Photo String FullName String Bio String Homepage string e-mail string timezone String Country string JabberaddressStaticconstraints ={fullName blank:falseBio Nullable:true, maxsize:1000Homepage URL:true, Nullable:trueEmail Email:true, Blank:falsePhoto Nullable:true, Maxsize:2 * 1024 * 1024Country Nullable:trueTimeZone Nullable:truejabberaddress Email:true, Nullable:true }}
Post.groovy:
Package com.grailsinaction class Post { String content Date dateCreated static constraints = { false< /c10> } static Belongsto = [User:user] static Hasmany = [Tags:tag] static mapping = {sort dateCreated: "desc"}}
Tag.groovy:
Package com.grailsinaction class Tag { String name user user static constraints = { false' c12/>} static hasmany = [Posts:post] static Belongsto = [User, Post]}
Userintegrationspec.groovy:
Packagecom.grailsinactionImportgrails.test.mixin.integration.IntegrationImportgrails.transaction.*Importspock.lang.*@Integration @rollbackclassUserintegrationspecextendsSpecification {def setup () {} def cleanup () {} def"Saving our first user to the database"() {given:"A Brand new User"def Joe=NewUser (loginId: ' Joe ', Password: ' Secret ')) When:"The user is saved"Joe.save () Then:"It saved successfully and can be found in the database"Joe.errors.errorCount= = 0joe.id!=NULLUser.get (joe.id). LoginId==Joe.loginid} def"Updating a saved user changes its properties"() {given:"An existing user"def Existinguser=NewUser (loginId: ' Joe ', Password: ' Secret ')) Existinguser.save (failOnError:true) When:"A property is changed"def Founduser=user.get (existinguser.id) Founduser.password= ' Sesame 'Founduser.save (failOnError:true) Then:The change was reflected in the databaseUser.get (existinguser.id). Password= = ' Sesame '} def"Deleting an existing user removes it from the database"() {given:"An existing user"def user=NewUser (loginId: ' Joe ', Password: ' Secret ')) User.save (failOnError:true) When:"The user is deleted"def Founduser=user.get (user.id) founduser.delete (flush:true) Then:The user is removed from the database!user.exists (founduser.id)} def"Saving a user with invalid properties causes an error"() {given:"A user which fails several field validations"def user=NewUser (loginId: ' Joe ', Password: ' Tiny ')) When:"The user is validated"user.validate () then:user.hasErrors ( )"Size.toosmall" = = User.errors.getFieldError ("Password"). Code"Tiny" = = User.errors.getFieldError ("Password"). Rejectedvalue!user.errors.getfielderror ("LoginId")} def"Recovering from a failed save by fixing invalid properties"() {given:"A user that has invalid properties"def Chuck=NewUser (loginId: ' Chuck ', Password: ' Tiny ')) assertChuck.save () = =NULL assertchuck.haserrors () When:"We Fix the invalid properties"Chuck.password= "Fistfist"chuck.validate () Then:"The user saves and validates fine"!chuck.haserrors () Chuck.save ()} def"Ensure a user can follow other users"() {given:"A Set of baseline users"def Joe=NewUser (loginId: ' Joe ', Password: ' Password ')). Save () def Jane=NewUser (loginId: ' Jane ', Password: ' Password ')). Save () def Jill=NewUser (loginId: ' Jill ', Password: ' Password ')). Save () When:"Joe follows Jan & Jill, and Jill follows Jane"joe.addtofollowing (Jane) joe.addtofollowing (Jill) jill.addtofollowing (Jane) Then:"Follower counts should match follow people" 2 = =joe.following.size ()1 = =jill.following.size ()}}
Postintegrationspec.groovy:
Packagecom.grailsinactionImportgrails.test.mixin.integration.IntegrationImportgrails.transaction.*Importspock.lang.*@Integration @rollbackclassPostintegrationspecextendsSpecification {def setup () {} def cleanup () {} def"Adding posts to user links post to user"() {given:"A Brand new User"def user=NewUser (loginId: ' Joe ', Password: ' Secret ')) User.save (failOnError:true) When:"Several posts is added to the user"user.addtoposts (NewPost (content: "First post.....w002!")) user.addtoposts (NewPost (content: "Second post ...")) user.addtoposts (NewPost (content: "Third post ....")) Then:"The user has a list of posts attached" 3 = =User.get (user.id). Posts.size ()} def"Ensure posts linked to a user can be retrieved"() {given:"A user with several posts"def user=NewUser (loginId: ' Joe ', Password: ' Secret ')) user.addtoposts (NewPost (content: "First")) user.addtoposts (NewPost (content: "Second")) user.addtoposts (NewPost (content: "Third")) User.save (failOnError:true) When:"The user is retrieved by their ID"def Founduser=User.get (user.id) def sortedpostcontent=FoundUser.posts.collect {it.content}.sort () Then:"The posts appear on the retrieved user"sortedpostcontent= = [' First ', ' Second ', ' third ']} def"Exercise tagging several post with various tags"() {given:"A user with a set of tags"def user=NewUser (loginId: ' Joe ', Password: ' Secret ')) def Taggroovy=NewTag (Name: "Groovy") def taggrails=NewTag (Name: "Grails")) user.addtotags (Taggroovy) user.addtotags (taggrails) user.save (failOnError:true) When:"The user tags fresh posts"def groovypost=NewPost (content: "A Groovy Post") user.addtoposts (groovypost) groovypost.addtotags (Taggroovy) def Bothpos T=NewPost (content: "A Groovy and Grails post") user.addtoposts (bothpost) bothpost.addtotags (Taggroovy) bothpost.addtotags (taggrail s) then:user.tags*.name.sort () = = [' Grails ', ' Groovy '] 1 = =groovyPost.tags.size ()2 = =bothPost.tags.size ()}}
Grails Domain Class One-to-one, one-to-many, many-to-many relationship summary and integration testing