2013-04-16 68 views
5

Tôi đang cố triển khai hai loại mối quan hệ khác nhau giữa hai lớp miền trong Grails.Grails: nhiều mối quan hệ giữa hai đối tượng miền

Hãy xem xét những điều sau; Tôi có hai lớp miền, một lớp Tác giả và Sách với một Tác giả có nhiều Sách.

class Author{   
    String name 
} 

class Book{ 
    String title 
    static belongsTo = [author:Author] 

} 

Ở trên mô tả mối quan hệ rất cơ bản giữa nhiều tác giả và sách. Nhưng tôi cũng muốn một Tác giả có khái niệm về danh sách các cuốn sách yêu thích. Điều này lý tưởng sẽ được biểu diễn như một mối quan hệ riêng biệt với nhiều mối quan hệ mô tả cùng một đối tượng Book như một danh sách và tồn tại như vậy.

class Author{   
    String name 
    static hasMany = [favouriteBooks: Book] 

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

class Book{ 
    String title 
    static belongsTo = [client:Client] 

} 

Tôi đã cố gắng mô tả điều này như trên (trong số nhiều phương pháp khác) và cuối cùng là bảng cơ sở dữ liệu (favourite_books) không được tạo. Tôi không nhận được bất kỳ lỗi nào. Đây là cách duy nhất tôi có thể nghĩ đến việc làm điều này mà không cần sử dụng thêm bất kỳ vật gì mà tôi muốn tránh để giữ cho mô hình đơn giản. Tôi cảm thấy tôi đang đi đúng hướng nhưng có thể thiếu một số phần quan trọng của câu đố.

Mọi trợ giúp sẽ được đánh giá cao.

+0

có bạn cố gắng ** sạch, xuất cảnh, grails ** một lần nữa, sau đó ** chạy ứng dụng **. Đôi khi grails không nhận thay đổi tên miền của bạn mà không có 'clean' – ikumen

+0

Trong ví dụ đầu tiên ở trên, bạn đang thiếu thuộc tính' hasMany' ở bên 'Author' và trong ví dụ thứ hai, không có tham chiếu đến' favouriteBooks' relatiionship trên bên 'Book'. –

Trả lời

2

Cuối cùng figured this out. Cảm ơn Don đã chỉ cho tôi theo hướng của trình cắm thêm db-reverse-engineer đã giúp trưng ra thuộc tính quan trọng cho phép chiến lược lập bản đồ này. Về cơ bản, tất cả đều sử dụng cài đặt liên kết mappedBy của GORM để cho Grails biết rõ ràng cách nhiều tham chiếu hasMany được ánh xạ. Các tập tin lớp học mà làm việc như sau:

class Author { 

    String name 
    static hasMany = [books: Book, favourites: Book] 

    // need to disambiguate the multiple hasMany references with the 
    // 'mappedBy' property: 
    static mappedBy = [books: "author", 
         favourites: "authors"] 
} 

class Book { 

    String title 
    Author author 

    static hasMany = [authors: Author] 
    static belongsTo = [Author] 
} 

Cảm ơn một lần nữa cho sự giúp đỡ

1

Sửa đổi Book lớp miền. Xóa ánh xạ author.

class Book{ 
    String title 
    static belongsTo = [Author] 
} 

Look cho bảng mới FAVORITE_BOOKS lần cleanrun-app.

4

Trước hết, hãy đảm bảo tôi hiểu vấn đề của bạn một cách chính xác. Bạn có BookAuthor lớp miền, nhưng có hai mối quan hệ giữa các lớp này:

  1. Một tác giả viết sách, vì vậy có một mối quan hệ một-nhiều giữa AuthorBook. Tất nhiên trong cuộc sống thực, một cuốn sách có thể được viết bởi nhiều tác giả, nhưng có vẻ như trong trường hợp này chúng ta có thể bỏ qua điều này.
  2. Tác giả có sách yêu thích, do đó, có mối quan hệ nhiều-nhiều thứ hai giữa AuthorBook. Mối quan hệ này rất nhiều vì một cuốn sách cụ thể có thể là một yêu thích của nhiều tác giả.

Giả sử tôi đã hiểu vấn đề chính xác, hãy thử tìm giải pháp. Trước hết, chúng ta hãy thêm nhiều-nhiều mối quan hệ (cuốn sách yêu thích):

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

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

Bất cứ khi nào một mối quan hệ nhiều-nhiều được định nghĩa chúng ta phải chọn một bên như là chủ sở hữu của mối quan hệ. Trong trường hợp này tôi đã chỉ định

static belongsTo = Author 

trong lớp Book, vì vậy Book là mặt thuộc sở hữu của các mối quan hệ và Author là chủ sở hữu. Bởi vì điều này chúng ta nên thêm sách yêu thích cho tác giả thay vì ngược lại, see here để biết thêm chi tiết.

Các mối quan hệ một-nhiều sau đó có thể được thêm vào với:

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

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

    Book writtenBy 
} 

Bằng cách này, trong mô hình tên miền của bạn bạn đã bao gồm những điều sau đây trong lớp Author

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

Điều này sẽ gây ra bảng tham gia được đặt tên thay vì favourite_books, trong khi đó trong mô hình của tôi, bảng tham gia sẽ mặc định là author_favourites. Nếu vì một lý do nào đó, bạn đặc biệt muốn bảng tham gia được đặt tên như thế này (ví dụ: bạn đang cố gắng ánh xạ các lớp tới các bảng hiện có), sau đó vui lòng bao gồm phần trên.

Cuối cùng, nếu bạn thấy mình phải vật lộn với việc xác định ánh xạ lớp miền, và cảm thấy thoải mái hơn với việc tạo ra các bảng, sau đó tạo ra các lớp miền từ họ, hãy kiểm tra this plugin

+0

Cảm ơn bạn đã phản hồi nhanh và chi tiết. Bạn đúng trong cách giải thích của bạn về những gì tôi đang cố gắng đạt được và trong khi nó hoạt động, tôi dường như có một vấn đề nhỏ với cách tiếp cận này. Tôi dường như kết thúc bằng một bảng author_books_written riêng để lập bản đồ quyền sở hữu tác giả của một cuốn sách. Tôi đã hy vọng chỉ đơn giản là có một author_id trong bảng Sách của tôi? Có thể vượt qua điều này không? – dre

+0

Nhân tiện, chúng ta có thể giả định rằng một cuốn sách chỉ có thể có một tác giả. – dre

Các vấn đề liên quan