Я почти наверняка делаю это задом наперед. Существует много путаницы вокруг этой функции, по-видимому, вокруг паутины.
Я просто пытаюсь создать связь с внешним ключом, в которой модель Book
имеет один Author
. Использование MySQL 8.
Когда я запрашиваю книгу, я хочу, чтобы объект автора был возвращен вместе с ней, поэтому возможно, что мой запрос также неверен ... Вот где я нахожусь.
моделей. go
package main
import (
"github.com/jinzhu/gorm"
uuid "github.com/satori/go.uuid"
"time"
)
/* Base Models
============================= */
type Base struct {
ID uuid.UUID `gorm:"primary_key" json:"id"`
CreatedAt *time.Time `json:"created_at"`
UpdatedAt *time.Time `gorm:"index" json:"updated_at"`
DeletedAt *time.Time `gorm:"index" json:"deleted_at"`
}
type BaseBook struct {
ISBN int64 `gorm:"primary_key;auto_increment:false;" json:"isbn"`
Description string `gorm:"type:longtext" json:"description"`
Author Author `gorm:"foreignkey:AuthorId" json:"author"`
AuthorId uuid.UUID `json:"author_id"`
Title string `json:"title"`
}
// BeforeCreate - Sets a UUID instead of incremental numeric ID.
func (base *Base) BeforeCreate(scope *gorm.Scope) error {
id := uuid.NewV4()
return scope.SetColumn("ID", id)
}
/* Tables
============================= */
type Book struct {
Base
BaseBook
Events []Event `gorm:"foreignkey:ISBN"`
}
type Event struct {
BaseBook
}
type Author struct {
Base
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Middle string `json:"middle"`
}
Есть ли проблема с тем, как я создаю записи здесь в функции seed?
обработчики. go
// GetSeedDatabase - Start seeding database with test data.
func GetSeedDatabase(w http.ResponseWriter, r *http.Request) {
authors := getSeedDataAuthors()
books := getSeedDataBooks()
for _, author := range authors {
for _, book := range books {
if book.Author == author.ID.String() {
newAuthor := Author{
Base: Base{
ID: author.ID,
},
FirstName: author.FirstName,
LastName: author.LastName,
Middle: author.Middle,
}
newBook := Book{
Base: Base{
ID: uuid.NewV4(),
},
BaseBook: BaseBook{
AuthorId: newAuthor.ID,
ISBN: book.ISBN,
Title: book.Title,
Description: book.Description,
},
}
MySQL.Create(newAuthor)
MySQL.Create(newBook)
}
}
}
var allAuthors []Author
MySQL.Find(&allAuthors)
var allBooks []Book
MySQL.Find(&allBooks)
if len(allAuthors) > 0 && len(allBooks) > 0 {
w.Write([]byte("successfully seeded database"))
return
}
w.Write([]byte("something went wrong seeding database"))
}
// GetAllBooks - Get all books in database.
func GetAllBooks(w http.ResponseWriter, r *http.Request) {
var allBooks []Book
MySQL.Find(&allBooks).Related(Author{})
json.NewEncoder(w).Encode(allBooks)
}
Когда я попадаю в конечную точку книги GetAllBooks
, ответ выглядит так:
[
{
"id": "0c266efa-3c3c-4bb8-abe6-dbb9b8000cd8",
"created_at": null,
"updated_at": null,
"deleted_at": null,
"isbn": 9781593275846,
"description": "JavaScript lies at the heart of almost every modern web application, from social apps to the newest browser-based games. Though simple for beginners to pick up and play with, JavaScript is a flexible, complex language that you can use to build full-scale applications.",
"author": {
"id": "00000000-0000-0000-0000-000000000000",
"created_at": null,
"updated_at": null,
"deleted_at": null,
"first_name": "",
"last_name": "",
"middle": ""
},
"author_id": "ba0d07bf-1a12-4742-989b-cdaa4c05ad72",
"title": "Eloquent JavaScript, Second Edition",
"Events": null
},
{
"id": "0ea3e0fc-f917-46ea-b55b-d97e916bacd9",
"created_at": null,
"updated_at": null,
"deleted_at": null,
"isbn": 9781491904244,
"description": "No matter how much experience you have with JavaScript, odds are you don’t fully understand the language. As part of the \"You Don’t Know JS\" series, this compact guide focuses on new features available in ECMAScript 6 (ES6), the latest version of the standard upon which JavaScript is built.",
"author": {
"id": "00000000-0000-0000-0000-000000000000",
"created_at": null,
"updated_at": null,
"deleted_at": null,
"first_name": "",
"last_name": "",
"middle": ""
},
"author_id": "c7f6e1b8-9e42-4666-bba8-dd9b229a362e",
"title": "You Don't Know JS",
"Events": null
}
]
Как видите, Author
возвращенные объекты являются их пустыми версиями.
Я все еще пробую различные комбинации примеров внешних ключей, которые я нашел в других местах, но все еще не повезло.
Обновление
Итак, первая проблема заключается в том, что GORM просто не добавляет внешние ключи, если вы пытаетесь добавить их с помощью аннотаций на моделях (как у меня). Может быть, это вещь MySQL8? Я не уверен, но я добавил отношение вручную так:
// addConstraints - Since GORM annotations are still broken for foreign keys we do it manually here.
func addConstraints(db *gorm.DB) *gorm.DB {
log.Println("adding db table constraints")
db.Model(Book{}).AddForeignKey(
"author_id",
"authors(id)",
"SET DEFAULT",
"SET DEFAULT",
)
return db
}
Теперь я могу предварительно загрузить данные об авторе, которые будут возвращены с книгами, например:
// GetAllBooks - Get all books in database.
func GetAllBooks(w http.ResponseWriter, r *http.Request) {
var allBooks []Book
MySQL.Preload("Author").Find(&allBooks)
json.NewEncoder(w).Encode(allBooks)
}