Grails: multiple relationships between two domain objects

前端 未结 3 859
孤城傲影
孤城傲影 2021-02-09 15:24

I am trying to implement two different types of relationships between two domain classes in Grails.

Consider the following; I have two domain classes, an Author and Book

3条回答
  •  慢半拍i
    慢半拍i (楼主)
    2021-02-09 15:37

    First of all, let's make sure I understand your problem correctly. You have Book and Author domain classes, but there are two relationships between these classes:

    1. An author writes books, so there's a one-to-many relationship between Author and Book. Of course in real life a book may be written by many authors, but it seems in this case we can ignore this.
    2. An author has favourite books, so there's a second many-to-many relationship between Author and Book. This relationship is many-to-many because a particular book could be a favourite of many authors.

    So assuming I've understood the problem correctly, let's try to find a solution. First of all, let's add the many-to-many relationship (favourite books):

    class Author {
        String name
        static hasMany = [favourites: Book]
    }
    
    class Book {
        String title
        static hasMany = [favouritedBy: Author]
        static belongsTo = Author
    }
    

    Whenever a many-to-many relationship is defined we have to choose one side as being the owner of the relationship. In this case I've specified

    static belongsTo = Author
    

    in the Book class, so Book is the owned side of the relationship and Author is the owner. Because of this we should add favourite books to authors rather than vice versa, see here for further details.

    The one-to-many relationship can then be added with:

    class Author {
        String name
        static hasMany = [favourites: Book, booksWritten: Book]
    }
    
    class Book {
        String title
        static hasMany = [favouritedBy: Author]
        static belongsTo = Author
    
        Book writtenBy
    }
    

    By the way, in your domain model you included the following in the Author class

    static mapping = {
        favouriteBooks joinTable: [name: 'favourite_books', key: 'author_id']
    }
    

    This will cause the join table to be named instead favourite_books, whereas in my model the join table will default to author_favourites. If for some reason you particularly want the join table to be named like this (e.g. you're trying to map the classes to existing tables), then feel free to include the above.

    Finally, if you find yourself struggling with defining domain class mappings, and are more comfortable with creating the tables, then generating the domain classes from them, check out this plugin

提交回复
热议问题