7

I have a struct definition in GO like this

package models

//StoryStatus indicates the current state of the story
type StoryStatus string

const (
    //Progress indicates a story is currenty being written
    Progress StoryStatus = "progress"
    //Completed indicates a story was completed
    Completed StoryStatus = "completed"
)

//Story holds detials of story
type Story struct {
    ID         int
    Title      string      `gorm:"type:varchar(100);unique_index"`
    Status     StoryStatus `sql:"type ENUM('progress', 'completed');default:'progress'"`
    Paragraphs []Paragraph `gorm:"ForeignKey:StoryID"`
}

//Paragraph is linked to a story
//A story can have around configurable paragraph
type Paragraph struct {
    ID        int
    StoryID   int
    Sentences []Sentence `gorm:"ForeignKey:ParagraphID"`
}

//Sentence are linked to paragraph
//A paragraph can have around configurable paragraphs
type Sentence struct {
    ID          uint
    Value       string
    Status      bool
    ParagraphID uint
}

I am using GORM for orm in GO. How do I fetch all the information for a story based on story id like all the paragraphs and all the sentences for each paragraph.

The GORM example show only with 2 models to use preload

2 Answers 2

6

This is what you're looking for:

db, err := gorm.Open("mysql", "user:password@/dbname?charset=utf8&parseTime=True&loc=Local")
defer db.Close()

story := &Story{}
db.Preload("Paragraphs").Preload("Paragraphs.Sentences").First(story, 1)

It finds the story with the id = 1 and preloads its relationships

fmt.Printf("%+v\n", story)

This prints out the result nicely for you

Side note: You can turn on log mode of Gorm so that you can see the underlying queries, to debug, or any other purposes:

db.LogMode(true)
1
  • 1
    I'm gonna make you a gold statue! I avoided hours of debugging.
    – FonzTech
    Commented Apr 30, 2022 at 11:33
0
    Looking this [example][1] this One to many.


package main

import (
    "log"

    "github.com/jinzhu/gorm"
    _ "github.com/jinzhu/gorm/dialects/sqlite"
    "github.com/kylelemons/godebug/pretty"
)

// Order
type Order struct {
    gorm.Model
    Status     string
    OrderItems []OrderItem
}

// Order line item
type OrderItem struct {
    gorm.Model
    OrderID  uint
    ItemID   uint
    Item     Item
    Quantity int
}

// Product
type Item struct {
    gorm.Model
    ItemName string
    Amount   float32
}

var (
    items = []Item{
        {ItemName: "Go Mug", Amount: 12.49},
        {ItemName: "Go Keychain", Amount: 6.95},
        {ItemName: "Go Tshirt", Amount: 17.99},
    }
)

func main() {
    db, err := gorm.Open("sqlite3", "/tmp/gorm.db")
    db.LogMode(true)
    if err != nil {
        log.Panic(err)
    }
    defer db.Close()

    // Migrate the schema
    db.AutoMigrate(&OrderItem{}, &Order{}, &Item{})

    // Create Items
    for index := range items {
        db.Create(&items[index])
    }
    order := Order{Status: "pending"}
    db.Create(&order)
    item1 := OrderItem{OrderID: order.ID, ItemID: items[0].ID, Quantity: 1}
    item2 := OrderItem{OrderID: order.ID, ItemID: items[1].ID, Quantity: 4}
    db.Create(&item1)
    db.Create(&item2)

    // Query with joins
    rows, err := db.Table("orders").Where("orders.id = ? and status = ?", order.ID, "pending").
        Joins("Join order_items on order_items.order_id = orders.id").
        Joins("Join items on items.id = order_items.id").
        Select("orders.id, orders.status, order_items.order_id, order_items.item_id, order_items.quantity" +
            ", items.item_name, items.amount").Rows()
    if err != nil {
        log.Panic(err)
    }

    defer rows.Close()
    // Values to load into
    newOrder := &Order{}
    newOrder.OrderItems = make([]OrderItem, 0)

    for rows.Next() {
        orderItem := OrderItem{}
        item := Item{}
        err = rows.Scan(&newOrder.ID, &newOrder.Status, &orderItem.OrderID, &orderItem.ItemID, &orderItem.Quantity, &item.ItemName, &item.Amount)
        if err != nil {
            log.Panic(err)
        }
        orderItem.Item = item
        newOrder.OrderItems = append(newOrder.OrderItems, orderItem)
    }
    log.Print(pretty.Sprint(newOrder))
}

      [1]: https://stackoverflow.com/questions/35821810/golang-gorm-one-to-many-with-has-one

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.