Grails In Action-03.Modeling the domain

9194 단어
Grails In Action은 Grails 기술을 사용해 허블(Hubbub)이라는 블로그 사이트를 구축한 것으로, 다음은 3장의 코드다.
제3장은 hubbub 블로그 구축에 필요한domain 대상을 설명하는데 중심은 모델 대상 관계이고 관련된 지식은 다음과 같다.
  • User와 Profile은 일대일 관계
  • User 및 User 자체 종속 관계
  • User와 Tag는 다대다 관계
  • User와 Post는 다대다 관계
  • 포스트와 태그는 다대다 관계
  • 검증
  • 정렬
  • lazy
  • ApplicationUser 및 User의 검증 속성 상속
  • spock 테스트, spock 테스트에 대한 자료는 많지 않지만 한번 해 볼 만하다.이거 볼 수 있어요
  • 모델 구축


    User.groovy
    
    package com.grailsinaction
    
    class User {
    
        String loginId
        String password
        Date dateCreated
    
        static hasOne = [ profile : Profile ]
        static hasMany = [ posts : Post, tags : Tag, following : User ]
    
        static constraints = {
            loginId size: 3..20, unique: true, blank: false
            password size: 6..8, blank: false
            profile nullable: true
        }
    
        static mapping = {
            profile lazy: false
        }
    }
    

    Profile.groovy
    
    package com.grailsinaction
    
    class Profile {
        User user
        byte[] photo
        String fullName
        String bio
        String homepage
        String email
        String timezone
        String country
        String jabberAddress
    
        static constraints = {
            fullName blank: false
            bio nullable: true, maxSize: 1000
            homepage url: true, nullable: true
            email email: true, nullable: false
            photo nullable: true
            country nullable: true
            timezone nullable: true
            jabberAddress email: true, nullable: true
        }
    }
    

    Post.groovy
    
    package com.grailsinaction
    
    class Post {
    
        String content
        Date dateCreated
    
        static belongsTo = [ user : User ]
    
        static hasMany = [ tags : Tag ]
    
        static constraints = {
            content blank: false
        }
    
        static mapping = {
            sort dateCreated: "desc"
        }
    }
    

    Tag.groovy
    
    package com.grailsinaction
    
    class Tag {
    
        String name
        User user
    
        static hasMany = [ posts : Post ]
        static belongsTo = [ User, Post ]
    
        static constraints = {
            name blank: false
        }
    }
    

    ApplicationUser.groovy
    
    package com.grailsinaction
    
    class ApplicationUser {
    
        String applicationName
        String password
        String apiKey
    
        static constraints = {
    
            importFrom User, include: ['password']
            applicationName blank: false, unique: true
            apiKey blank: false
        }
    }
    

    통합 테스트


    UserIntegrationSpec.groovy
    
    package com.grailsinaction
    
    import grails.plugin.spock.IntegrationSpec
    
    class UserIntegrationSpec extends IntegrationSpec {
    
        def "Saving our first user to the database"() {
    
            given: "A brand new user"
                def joe = new User(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 == 0
                joe.id != null
                User.get(joe.id).loginId == joe.loginId
        }
    
        def "Deleting an existing user removes it from the database"() {
    
            given: "An existing user"
                def user = new User(loginId: 'joe', password: 'secret').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 = new User(loginId: 'chuck_norris', 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")
    
                // 'homepage' is now on the Profile class, so is not validated.
        }
    
        def "Recovering from a failed save by fixing invalid properties"() {
    
            given: "A user that has invalid properties"
                def chuck = new User(loginId: 'chuck_norris', password: 'tiny')
                assert chuck.save() == null
                assert chuck.hasErrors()
    
             when: "We fix the invalid properties"
                chuck.password = "fistfist"
    
                // 'homepage' is now on Profile so can't be set on the user.
    
            then: "The user saves and validates fine"
                chuck.validate()
                !chuck.hasErrors()
                chuck.save()
        }
    
        def "Ensure a user can follow other users"() {
    
            given: "A set of baseline users"
                def glen = new User(loginId: 'glen', password:'password').save()
                def peter = new User(loginId: 'peter', password:'password').save()
                def sven = new User(loginId: 'sven', password:'password').save()
    
            when: "Glen follows Peter, and Sven follows Peter"
                glen.addToFollowing(peter)
                glen.addToFollowing(sven)
                sven.addToFollowing(peter)
    
            then: "Follower counts should match following people"
                2 == glen.following.size()
                1 == sven.following.size()
        }
    }
    

    PostIntegrationSpec.groovy
    
    package com.grailsinaction
    
    import grails.plugin.spock.IntegrationSpec
    
    class PostIntegrationSpec extends IntegrationSpec {
    
       def "Adding posts to user links post to user"() {
    
            given: "A brand new user"
                def user = new User(loginId: 'joe',password: 'secret').save(failOnError: true)
    
            when: "Several posts are added to the user"
                user.addToPosts(new Post(content: "First post... W00t!"))
                user.addToPosts(new Post(content: "Second post..."))
                user.addToPosts(new Post(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 = new User(loginId: 'joe', password: 'secret').save(failOnError: true)
                user.addToPosts(new Post(content: "First"))
                user.addToPosts(new Post(content: "Second"))
                user.addToPosts(new Post(content: "Third"))
    
            when: "The user is retrieved by their id"
                def foundUser = User.get(user.id)
                List<String> sortedPostContent = foundUser.posts.collect { it.content }.sort()
    
            then: "The posts appear on the retrieved user"
                sortedPostContent == ['First', 'Second', 'Third']
        }
    
        def "Exercise tagging several posts with various tags"() {
    
            given: "A user with a set of tags"
                def user = new User(loginId: 'joe', password: 'secret').save(failOnError: true)
                def tagGroovy = new Tag(name: 'groovy')
                def tagGrails = new Tag(name: 'grails')
                user.addToTags(tagGroovy)
                user.addToTags(tagGrails)
    
            when: "The user tags two fresh posts"
                def groovyPost = new Post(content: "A groovy post")
                user.addToPosts(groovyPost)
                groovyPost.addToTags(tagGroovy)
    
                def bothPost = new Post(content: "A groovy and grails post")
                user.addToPosts(bothPost)
                bothPost.addToTags(tagGroovy)
                bothPost.addToTags(tagGrails)
    
            then:
                user.tags*.name.sort() == ['grails', 'groovy']
                1 == groovyPost.tags.size()
                2 == bothPost.tags.size()
        }
    }
    

    ApplicationUserIntegrationSpec.groovy
    
    package com.grailsinaction
    
    import grails.plugin.spock.IntegrationSpec
    
    class ApplicationUserIntegrationSpec extends IntegrationSpec {
    
        def "Recovering from a failed save by fixing invalid properties"() {
    
            given: "A user that has invalid properties"
                def chuck = new ApplicationUser(applicationName: 'chuck_bot', password: 'tiny', apiKey: 'cafebeef00')
                assert chuck.save() == null
                assert chuck.hasErrors()
    
            when: "We fix the invalid properties"
                chuck.password = "fistfist"
                chuck.save(failOnError: true)
    
            then: "The user saves and validates fine"
                chuck.validate()
                !chuck.hasErrors()
                chuck.save()
                println chuck.findAll()
        }
    }
    

    코드 다운로드


    소재지

    좋은 웹페이지 즐겨찾기