การเล่น Relation กับ GORM
Association Mode With GORM
Ref: https://gorm.io/docs/associations.html
ลองเปลี่ยน model ให้ลึกซึ้งขึ้น
models.go
package main
import (
"gorm.io/gorm"
)
type Book struct {
gorm.Model
Name string `json:"name"`
Author string `json:"author"`
Description string `json:"description"`
PublisherID uint
Publisher Publisher
Authors []Author `gorm:"many2many:author_books;"`
}
type Publisher struct {
gorm.Model
Details string
Name string
}
type Author struct {
gorm.Model
Name string
Books []Book `gorm:"many2many:author_books;"`
}
type AuthorBook struct {
AuthorID uint
Author Author
BookID uint
Book Book
}
func createPublisher(db *gorm.DB, publisher *Publisher) error {
result := db.Create(publisher)
if result.Error != nil {
return result.Error
}
return nil
}
func createAuthor(db *gorm.DB, author *Author) error {
result := db.Create(author)
if result.Error != nil {
return result.Error
}
return nil
}
func createBookWithAuthor(db *gorm.DB, book *Book, authorIDs []uint) error {
// First, create the book
if err := db.Create(book).Error; err != nil {
return err
}
return nil
}
func getBookWithPublisher(db *gorm.DB, bookID uint) (*Book, error) {
var book Book
result := db.Preload("Publisher").First(&book, bookID)
if result.Error != nil {
return nil, result.Error
}
return &book, nil
}
func getBookWithAuthors(db *gorm.DB, bookID uint) (*Book, error) {
var book Book
result := db.Preload("Authors").First(&book, bookID)
if result.Error != nil {
return nil, result.Error
}
return &book, nil
}
func listBooksOfAuthor(db *gorm.DB, authorID uint) ([]Book, error) {
var books []Book
result := db.Joins("JOIN author_books on author_books.book_id = books.id").
Where("author_books.author_id = ?", authorID).
Find(&books)
if result.Error != nil {
return nil, result.Error
}
return books, nil
}
เวลาเรียกใช้งานที่ main.go
main.go
func main() {
// Migrate the schema
db.AutoMigrate(&Book{}, &Publisher{}, &Author{}, &AuthorBook{})
// ขาสร้าง
publisher := Publisher{
Details: "Publisher Details",
Name: "Publisher Name",
}
_ = createPublisher(db, &publisher)
// Example data for a new author
author := Author{
Name: "Author Name",
}
_ = createAuthor(db, &author)
// // Example data for a new book with an author
book := Book{
Name: "Book Title",
Author: "Book Author",
Description: "Book Description",
PublisherID: publisher.ID, // Use the ID of the publisher created above
Authors: []Author{author}, // Add the created author
}
_ = createBookWithAuthor(db, &book, []uint{author.ID})
// ขาเรียก
// Example: Get a book with its publisher
bookWithPublisher, err := getBookWithPublisher(db, 1) // assuming a book with ID 1
if err != nil {
// Handle error
}
// Example: Get a book with its authors
bookWithAuthors, err := getBookWithAuthors(db, 1) // assuming a book with ID 1
if err != nil {
// Handle error
}
// Example: List books of a specific author
authorBooks, err := listBooksOfAuthor(db, 1) // assuming an author with ID 1
if err != nil {
// Handle error
}
fmt.Println(bookWithPublisher)
fmt.Println(bookWithAuthors)
fmt.Println(authorBooks)
}
เรื่องอื่นๆ ของ GORM
Gorm support การทำ
SQL Builder
Preload (improve Join Query)
Session
Transaction