Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk mengembalikan entiti bersarang selepas mencipta objek baharu?

Bagaimana untuk mengembalikan entiti bersarang selepas mencipta objek baharu?

PHPz
PHPzke hadapan
2024-02-10 21:40:15538semak imbas

Bagaimana untuk mengembalikan entiti bersarang selepas mencipta objek baharu?

Dalam PHP, cara mengembalikan entiti bersarang selepas mencipta objek baharu ialah soalan biasa. Apabila kita perlu mencipta objek baharu dalam kelas dan menggunakannya sebagai atribut entiti lain, kita perlu memberi perhatian kepada beberapa teknik dan kaedah. Pertama, kita boleh mencipta objek baharu dalam pembina kelas dan menetapkannya kepada harta. Kami kemudiannya boleh menggunakan kata kunci $ini untuk merujuk objek semasa dan mengakses sifatnya. Selain itu, kita juga boleh menggunakan kaedah statik atau corak kilang untuk mencipta objek baharu dan mengembalikannya kepada pemanggil. Tanpa mengira kaedah, kunci untuk mengembalikan entiti bersarang adalah dengan betul mengendalikan perhubungan antara objek dan memastikan ia berinteraksi dan menghantar data dengan betul antara entiti. Melalui kaedah ini, kami boleh mencipta dan mengembalikan objek entiti bersarang dalam PHP dengan mudah.

Kandungan soalan

Model account 包含嵌套结构 - currencyuser

Apabila saya mencipta tika baharu account dalam pangkalan data dan kemudian mengembalikannya dalam respons, entiti bersarang kosong:

type account struct {
    basemodel
    name       string          `gorm:"size:64;not null" json:"name"`
    balance    decimal.decimal `gorm:"type:decimal(16, 2);default:0;not null;" json:"balance"`
    userid     int             `gorm:"not null" json:"-"`
    user       user            `gorm:"foreignkey:userid" json:"user"`
    currencyid int             `gorm:"not null" json:"-"`
    currency   currency        `gorm:"foreignkey:currencyid" json:"currency"`
}

type createaccountbody struct {
    name       string          `json:"name" binding:"required"`
    balance    decimal.decimal `json:"balance"`
    currencyid int             `json:"currency_id" binding:"required"`
}

func createaccount(ctx *gin.context) {
    body := createaccountbody{}

    if err := ctx.bind(&body); err != nil {
        log.println("error while binding body:", err)
        ctx.json(
            http.statusbadrequest,
            gin.h{"error": "wrong request parameters"},
        )
        return
    }

    account := account {
        name:       body.name,
        balance:    body.balance,
        currencyid: body.currencyid,
        userid:     1,
    }
    
    if result := db.db.create(&account); result.error != nil {
        log.println("unable to create an account:", result.error)
    }    

    ctx.json(http.statuscreated, gin.h{"data": account})
}


Untuk mengelakkan masalah ini, saya menggunakan pertanyaan berasingan untuk memuat semula pembolehubah akaun:

db.DB.Create(&account)
db.DB.Preload("User").Preload("Currency").Find(&account, account.ID)
ctx.JSON(http.StatusCreated, gin.H{"data": account})

Adakah ini cara yang paling berkesan dan betul untuk mencapai hasil yang diinginkan?

Penyelesaian

Saya akan berkongsi dengan anda bagaimana saya biasanya mengendalikan situasi ini. Pertama, izinkan saya berkongsi kod.

main.go Fail

package main

import (
    "context"

    "gogindemo/handlers"

    "github.com/gin-gonic/gin"
    "gorm.io/driver/postgres"
    "gorm.io/gorm"
)

var (
    db  *gorm.db
    ctx *gin.context
)

func init() {
    dsn := "host=localhost user=postgres password=postgres dbname=postgres port=5432 sslmode=disable"
    var err error
    db, err = gorm.open(postgres.open(dsn), &gorm.config{})
    if err != nil {
        panic(err)
    }

    db.automigrate(&handlers.currency{})
    db.automigrate(&handlers.user{})
    db.automigrate(&handlers.account{})
}

func adddb() gin.handlerfunc {
    return func(ctx *gin.context) {
        ctx.request = ctx.request.withcontext(context.withvalue(ctx.request.context(), "db", db))
        ctx.next()
    }
}

func main() {
    db.create(&handlers.user{id: 1, name: "john doe"})
    db.create(&handlers.user{id: 2, name: "mary hut"})
    db.create(&handlers.currency{id: 1, name: "eur"})
    db.create(&handlers.currency{id: 2, name: "usd"})

    r := gin.default()
    r.post("/account", adddb(), handlers.createaccount)

    r.run()
}

Di sini saya baru menambah kod untuk bootstrap objek pangkalan data dan menambah beberapa data tiruan padanya.

handlers/handlers.go Fail

package handlers

import (
    "net/http"

    "github.com/gin-gonic/gin"
    "github.com/shopspring/decimal"
    "gorm.io/gorm"
)

type User struct {
    Id   int
    Name string
}

type Currency struct {
    Id   int
    Name string
}

type Account struct {
    Id         int
    Name       string          `gorm:"size:64;not null" json:"name"`
    Balance    decimal.Decimal `gorm:"type:decimal(16, 2);default:0;not null;" json:"balance"`
    UserID     int             `gorm:"not null" json:"-"`
    User       User            `gorm:"foreignKey:UserID" json:"user"`
    CurrencyID int             `gorm:"not null" json:"-"`
    Currency   Currency        `gorm:"foreignKey:CurrencyID" json:"currency"`
}

type CreateAccountBody struct {
    Name       string          `json:"name" binding:"required"`
    Balance    decimal.Decimal `json:"balance"`
    CurrencyID int             `json:"currency_id" binding:"required"`
}

func CreateAccount(c *gin.Context) {
    db, ok := c.Request.Context().Value("DB").(*gorm.DB)
    if !ok {
        c.JSON(http.StatusInternalServerError, gin.H{"error": "internal server error"})
        return
    }
    var accountReq CreateAccountBody
    if err := c.BindJSON(&accountReq); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": "wrong request body payload"})
        return
    }

    // create Account & update the "account" variable
    account := Account{Name: accountReq.Name, Balance: accountReq.Balance, CurrencyID: accountReq.CurrencyID, UserID: 1}
    db.Create(&account).Preload("Currency").Preload("User").Find(&account, account.Id)

    c.IndentedJSON(http.StatusCreated, account)
}

Dalam fail ini, saya sebenarnya berkomunikasi dengan pangkalan data dengan melakukannya dalam context 中传递的 db . Sekarang, kembali kepada soalan anda.
Jika hubungan antara mata wang//akaun dan user/currency//account 和 user/account 之间的关系是 1:1 类型,那么,您应该依赖 preload 子句。这将在单独的查询中加载相关实体,而不是将其添加到 inner join ialah jenis 1:1 , maka anda harus bergantung pada klausa pramuat. Ini akan memuatkan entiti yang berkaitan dalam pertanyaan berasingan dan bukannya menambahkannya pada klausa inner join.

Sila beritahu saya jika ini menyelesaikan masalah anda, terima kasih!

Atas ialah kandungan terperinci Bagaimana untuk mengembalikan entiti bersarang selepas mencipta objek baharu?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam