Skip to main content

การเล่น 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