I'm trying to model a warehouse. Now I have my stuff setup and know how I want to model it, but I don't know how to select stuff here the right way with gorm.
I have the following types:
type Store struct {
StoreID int `gorm:"primary_key;AUTO_INCREMENT;not null"`
Name string `gorm:"not null"`
Adress string `gorm:"not null"`
Manager User `gorm:"not null"`
ManagerID int `gorm:"foreignkey:ManagerID;not null"`
Boxes []Box `gorm:"foreignkey:StoreID;association_foreignkey:StoreID"`
}
type User struct {
UserID int `json:"id" gorm:"primary_key;AUTO_INCREMENT;not null"`
Username string `json:"username" gorm:"not null"`
Password string `json:"password" gorm:"not null"`
Email string `json:"email" gorm:"not null"`
Right UserRight `json:"userright" gorm:"not null"`
}
type Box struct {
BoxID int `gorm:"primary_key;AUTO_INCREMENT;not null"`
StoreID int `gorm:"not null"`
Code int `gorm:"type:integer(13)"`
Description string `gorm:"not null"`
}
Now I'd like to select All Boxes, with their associated Stores aswell as the associated Mangers to said Stores.
Do I have to do this with a join or has gorm a nicer method for this?
try
boxes := []Box{}
db.Model(&Box{}).Preload("Store.Manager").Find(&boxes)
Related
Always got an error when I add the relationship to the User in GitUser struct.
type GitUser struct {
ID uint `json:"id" gorm:"primaryKey"`
ExternalID string
JobID uint
UserID uint
User User `gorm:"foreignKey:UserID;references:ID"`
Job Job `gorm:"foreignKey:JobID;references:ID"`
}
type User struct {
ID uint `json:"id" gorm:"primaryKey"`
ExternalId *string
Username string
Email string
Name string
HashedPassword *string
AvatarUrl *string
IsAdmin bool
LastSignInAt *time.Time
CreatedAt time.Time
UpdatedAt time.Time
IsArchived bool
GitUser []GitUser
}
I'm trying to make a mutual relationship between User and GitUser
So I have two structs User and Company which are as follows
//Company
type Company struct {
Id int `json:"id" gorm:"primaryKey;autoIncrement;type:int"`
Poc_name string `json:"poc_name" gorm:"type:string;size:128;not null"`
Poc_title string `json:"poc_title" gorm:"type:string;size:255;not null"`
Poc_email string `json:"poc_email" gorm:"type:string;size:128;not null"`
Poc_phone string `json:"poc_phone" gorm:"type:string;size:128;not null"`
Default_driver_commission float32 `json:"default_driver_commission" gorm:"type:float;default:12;not null"`
Mc_number string `json:"mc_number" gorm:"type:string;size:128;default:null"`
Us_dot_number string `json:"us_dot_number" gorm:"type:string;size:128;default:null"`
Fk_user_id int `json:"fk_user_id" gorm:"not null;type:int"`
Fk_user Users `json:"user" gorm:"foreignKey:Fk_user_id"`
Time_created time.Time `json:"time_created" gorm:"autoCreateTime;not null"`
Time_updated time.Time `json:"time_updated" gorm:"autoCreateTime;not null"`
}
//User
type Users struct {
Id int `json:"id" gorm:"primaryKey;autoIncrement;type:int"`
Username string `json:"username" gorm:"unique;not null;type:string;size:128"`
Email string `json:"email" gorm:"unique;not null;type:string;size:128"`
Password string `gorm:"not null;type:string;size:255"`
Phone string `json:"phone" gorm:"not null;type:string;size:128"`
First_name string `json:"first_name" gorm:"not null;type:string;size:128"`
Last_name string `json:"last_name" gorm:"not null;type:string;size:128"`
Provider string `json:"provider" gorm:"not null;type:string;size:128"`
Profile_picture_url string `json:"profile_picture_url" gorm:"type:text"`
Is_verified bool `json:"is_verified" gorm:"default:true;not null"`
Stripe_id string `json:"stripe_id" gorm:"not null;type:string;size:350"`
Fcm_token string `json:"fcm_token" gorm:"not null;type:string;size:350"`
Web_fcm_token string `json:"web_fcm_token" gorm:"not null;type:string;size:350"`
Hour_format_12 bool `json:"hour_format_12" gorm:"not null;default:false"`
Temp_in_centi bool `json:"temp_in_centi" gorm:"not null;default:false"`
Map_pref string `json:"map_pref" gorm:"not null;type:string;size:350"`
Time_created time.Time `json:"time_created" gorm:"autoCreateTime;not null"`
Time_updated time.Time `json:"time_updated" gorm:"autoCreateTime;not null"`
User_type int `json:"user_type" gorm:"not null"`
Address_id int `json:"address_id" gorm:"not null"`
Fk_address Address `json:"address" gorm:"foreignKey:Address_id"`
}
And this is my api call
func GetUserById(c *fiber.Ctx) error {
id, err := c.ParamsInt("id")
// var user models.Company
var user models.Users
if err != nil {
return c.Status(400).JSON("Please Ensure that :id is an integer")
}
// database.Database.Db.Preload("Fk_user.Fk_address").Where("Fk_user_id = ?", id).Find(&user)
database.Database.Db.Preload("Fk_address").Find(&user, id)
if user.Id == 0 {
return c.Status(404).JSON("User Does Not Exists")
}
// log.Fatalln(responseuser.Fk_address)
return c.Status(200).JSON(&user)
}
How can I access the company object from the user object. Previously we using Flask and SQAlchemy and it was made possible by back_ref. Is there anything similar in Gorm and Fiber ? thanks
I'm trying to create a belongs to relation between two database tables, using GORM, my code is the following:
type Shop struct {
ID uuid.UUID `json:"id" gorm:"primaryKey;type:uuid"`
Name string `json:"name" gorm:"not null" validate:"required"`
City string `json:"city" gorm:"not null" validate:"required"`
State string `json:"state" gorm:"not null" validate:"required"`
}
type Employee struct {
ID uuid.UUID `json:"id" gorm:"primaryKey;type:uuid"`
FirstName string `json:"first_name" gorm:"not null" validate:"required"`
LastName string `json:"last_name" gorm:"not null" validate:"required"`
Email string `json:"email" gorm:"not null;unique" validate:"required,email"`
Password string `json:"password" gorm:"not null" validate:"required"`
Active bool `json:"active" gorm:"not null;default:false"`
ShopId uuid.UUID `json:"shop_id" gorm:"type:uuid"`
Shop Shop `gorm:"foreignKey:ShopID"`
}
When I run the migrations, this error pops up:
[error] invalid field found for struct .../.../.../api/models.Employee's field Shop: define a valid foreign key for relations or implement the Valuer/Scanner interface
I've found some references using number primary keys and they seem to work fine, but I can't find any solution to work with uuids...
I'm not sure, but what I understand of the message error is that the type uuid.UUID doesn't have implemented the methods for the interfaces Valuer and Scanner.
You should create your own type UUID, which can be something like this:
type UUID uuid.UUID
func(id UUID) Value() (driver.Value, error) {
return id.String(), nil
}
func (id *UUID) Scan(value interface{}) error {
dbID, ok := value.(string)
if !ok {
return errors.New("id scan: invalid value")
}
*e = uuid.MustParse(dbID)
return nil
}
And use it on your struct's definitions:
type Shop struct {
ID UUID `json:"id" gorm:"primaryKey;type:uuid"`
//...
}
Is it possible to use many to many between 3 models?
I have 3 models I want to join into a bridge table "client_operator_role"
Operator
type Operator struct {
gorm.Model
Title string `gorm:"unique;not null" validate:"required,min=1,max=100"`
Email string `gorm:"not null;unique" validate:"required,email"`
Mobile string `gorm:"not null" validate:"required,min=7,max=15,numeric"`
Last_online time.Time `gorm:"default:null" validate:"omitempty"`
Last_ip string `gorm:"default:null" validate:"omitempty,ip"`
Clients []*Client `gorm:"many2many:client_operator_role;"`
Cli_ids []string `gorm:"-:all" validate:"omitempty,dive,numeric"` // placeholder field, wont be part of table
GoadminCustomUser GoadminCustomUser `validate:"omitempty,dive"`
}
Client
type Client struct {
gorm.Model
Name string `gorm:"unique;not null" validate:"required,min=1,max=30"`
Kyc_status string `gorm:"not null" validate:"required,min=1,max=30"`
Kyc_remarks string `gorm:"default:null" validate:"omitempty,min=0,max=200"`
Operators []*Operator `gorm:"many2many:client_operator_role;"`
Op_ids []string `gorm:"-:all" validate:"omitempty,dive,numeric"` // placeholder field, wont be part of table
Users []User
}
Role
type GoadminRole struct {
ID uint `gorm:"primaryKey"`
Name string
Slug string
CreatedAt time.Time
UpdatedAt time.Time
Operators []*Operator `gorm:"many2many:client_operator_role;"`
}
Gorm docs state many2many is only for 2 models. Is there a workaround to join these three?
I want to use smart select when querying rooms table. When use the original struct it works fine but when use smart select it fails.
Here is my schema
type Room struct {
gorm.Model
ID uint `json:"id" gorm:"primary_key"`
Hash string `json:"hash" binding:"required" gorm:"not null:true"`
Users []User `json:"users" gorm:"many2many:room_users"`
Messages []Message `json:"messages"`
}
type RoomAPI struct {
ID uint `json:"id" gorm:"primary_key"`
Hash string `json:"hash" binding:"required" gorm:"not null:true"`
Users []User `json:"users" gorm:"many2many:room_users"`
//Messages []Message `json:"messages" gorm:"foreignKey:RoomID"`
}
func (RoomAPI) TableName() string {
return "rooms"
}
type User struct {
gorm.Model
ID uint `json:"id" gorm:"primary_key"`
Name string `json:"name" binding:"required" gorm:"not null:true"`
Phone string `json:"phone"`
Email string `json:"email" binding:"required,email" gorm:"not null:true"`
Password string `json:"password" binding:"required,min=8" gorm:"not null:true"`
Gender string `json:"gender" binding:"Enum=male_female" gorm:"type:gender;not null:true;default:male"`
Rooms []Room `json:"rooms" gorm:"many2many:room_users"`
}
type Message struct {
gorm.Model
ID uint `json:"id" gorm:"primary_key"`
Text string `json:"text" binding:"required" gorm:"not null:true"`
UserID uint `json:"user_id" gorm:"not null:true"`
RoomID uint `json:"room_id" gorm:"not null:true"`
}
here is my query
var rooms []RoomAPI
user := User{ID: userId}
err := db.DB.Model(&user).Preload("Users").
Association("Rooms").
Find(&rooms)
if err != nil {
log.Printf("err -> %+v", err)
return err, nil
}
return nil, rooms
I want to get rooms with selected fields with smart select but it fails