简体   繁体   中英

Get GORM model row based on foreign key relationship (golang)

I am using Golang (GORM) + Postgres. I am trying to model a business situation where a seller sells things to buyers, each creating an order transaction.

I have an Order Gorm model, as well as a Buyer and a Seller Gorm model. The Buyer and the Seller are already rows created in the database.

One buyer HasMany orders.

One seller HasMany orders.

To map out this relation, I believe I just create the respective Buyer/Seller struct (standard Gorm models), and then make an Order struct like so:

type Order struct {
    ID        int64       `json:"ID"gorm:"primary_key;auto_increment:true"`
    Buyer     *Buyer      `json:"Buyer"`
    Seller    *Seller     `json:"Seller"`
    // ... other data ...
}

I'm assuming the above automatically creates the relationship, but I am not entirely sure . I can create an Order with this function, and this returns fine:

func CreateOrder(buyer *entity.Buyer, seller *entity.Seller) (*entity.Order, error) {
    order := &entity.Order{
        User:   buyer,
        Sitter: seller,
        // ... other data ...
    }
    db.Table("orders").Create(order)
    return order
}

If I go to Postgres CLI, the TABLE orders; does not show the columns buyer or seller. I would expect a column of their IDs. So this is why I am unsure this is working. This could definitely be a problem in itself.

Anyways, what I really want to do is be able to check if any orders currently exist for a Buyer / Seller. But I don't really see anyway to do that with gorm queries. I would imagine in SQL it would be something like:

func FindOrder(buyer *entity.Buyer, seller *entity.Seller) {
     db.Raw(`GET order FROM orders WHERE buyer = ?, seller = ?`, buyer, seller)
     // OR this ???
     db.Table("orders").First(buyer, buyer).First(seller, seller)
}

But I don't know of any Gorm helper function that actually does this. I also want this to be efficient because buyer and seller each have their ID primary keys.

How can I find an Order based on the Buyer / Seller like in the example above?

As an alternative, I am thinking of adding (buyer ID + seller ID) to make a custom order ID primary_key . This seems hacky though, as I feel like the whole point of relations is so I don't have to do something like this.

If you need to see the seller id and the buyer id in the orders table, include two fields for that in your orders struct, also you can use the foreignKey tag to populate those fields (by default they are populated with the primary id of the associated table record, you can use references tag as mentioned here to change that).

type Order struct {
    ID int64 `json:"id" gorm:"primary_key;auto_increment:true"`
    BuyerID int64 `json:"buyer_id" gorm:"index"`
    SellerID int64 `json:"seller_id" gorm:"index"`
    Buyer *Buyer `json:"buyer" gorm:"foreignKey:BuyerID"`
    Seller *Seller  `json:"seller" gorm:"foreignKey:SellerID"`
}

type Buyer struct {
    ID int64    `json:"id" gorm:"primary_key;auto_increment:true"`
    Name string `json:"name"`
}

type Seller struct {
    ID int64    `json:"id" gorm:"primary_key;auto_increment:true"`
    Name string  `json:"name"`
}

As for the function to find orders given the buyer AND the seller you can use something like,

func findOrders(db *gorm.DB, buyerID int,sellerID int)[]Order{
    orders := make([]Order,0)
    db.Where("buyer_id=? AND seller_id=?",buyerID,sellerID).Find(&Order{}).Scan(&orders)
    return orders
}

in contrast if you need to find orders for a given buyer OR the seller,

func findOrder(db *gorm.DB, buyerID int,sellerID int)[]Order{
    orders := make([]Order,0)
    db.Where("buyer_id=? OR seller_id=?",buyerID,sellerID).Find(&Order{}).Distinct().Scan(&orders)
    return orders
}

The index tag covers the indexing requirement for orders table.

在此处输入图片说明

对大型查询使用简单的原始查询构建器https://perfilovstanislav.github.io/go-raw-postgresql-builder/#simple-example

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM