I have a table with golang struct like this:
Order {
ID
TransactionID
Transaction
}
Transaction {
ID
ProfileID
Profile
}
Profile {
ID
AccountID
Account
}
How to get all the order with condition of account id with gorm? I have tried this:
var orders []*Order
res := r.db.
Joins("Transaction").
Preload("Transaction.Profile").
Where("Transaction.Profile.account_id = 1").
Find(&orders)
But it does not work.
This solution should work based on the structs definitions you provided. First, let me show the code and then I'll go through each step:
package main
import (
"fmt"
_ "github.com/lib/pq"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
type Order struct {
Id int
TransactionId int
Transaction Transaction
}
type Transaction struct {
Id int
ProfileId int
Profile Profile
}
type Profile struct {
Id int
AccountId int
Account Account
}
type Account struct {
Id int
}
func main() {
dsn := "host=localhost user=postgres password=postgres dbname=postgres port=5432 sslmode=disable"
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
panic(err)
}
db.AutoMigrate(&Account{})
db.AutoMigrate(&Profile{})
db.AutoMigrate(&Transaction{})
db.AutoMigrate(&Order{})
db.Create(&Account{})
db.Create(&Profile{AccountId: 1})
db.Create(&Transaction{ProfileId: 1})
db.Create(&Order{TransactionId: 1})
// order + transaction + profile + account
var order Order
db.Debug().Preload("Transaction.Profile.Account").Joins("inner join transactions t on orders.transaction_id = t.id").Joins("inner join profiles p on p.id = t.profile_id").Joins("inner join accounts a on p.account_id = a.id").First(&order, "a.id = ?", 1)
fmt.Println(order)
}
Let's take a closer look at the code.
Nothing changed here. Be sure to know the GORM conventions when you declare the structs as GORM will create relations, foreign keys, and constraints based on this.
Here, you can find the connection to Postgres, the auto-migrating commands to synchronize the tables, and the insert of some dummy data.
Here, we used a lot of methods provided by the GORM package for Go. Let's recap them in a short list:
Debug
: it prints to the console the Raw SQL query. It's useful when dealing with complex queriesPreload
: loads the related entities but it doesn't include them in the final query produced by GormJoins
: it specifies which tables have to be referenced in a JOIN clause. With the Joins
we add the clause to the query.First
: it's used both for fetching only one record and also for specifying some filter such as in our case (e.g. a.id = ?
).Let me know if this clarifies your issue, thanks!