How to retrieve parent table using child table in Gorm - postgresql

i'm new to Golang and facing retriving child table data that container id refer to parent table id. In the documentation shows that only the parent can retrieve child using preload method but didn't show how to retrieve reversed back.
(one to many relationship)
Parent Table
type User struct {
Id uuid.UUID `gorm:"type:uuid;default:gen_random_uuid()" json:"id"`
Username string `json:"username"`
Password string `json:"password,omitempty"`
Email string `json:"email"`
Gender string `json:"gender"`
Alias string `json:"alias"`
RefreshToken *string `json:"refresh_token,omitempty"`
AccessToken *string `json:"access_token,omitempty"`
DateOfBirth *time.Time `json:"date_of_birth"`
LastLoggedIn *time.Time `json:"last_logged_in"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Account []Account `json:"account"`
}
Child Table
type Account struct {
Id uuid.UUID `gorm:"type:uuid;default:gen_random_uuid()" json:"id"`
Name string `json:"name"`
Balance float32 `json:"balance"`
UserId string `json:"user_id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
Was hoping that can return json like this:
[{
"Id":"xxx",
....
User: {"Id":"xxx"}
}]
I'm not sure is this possible or not but prisma did it, sorry for disturb your time and have a nice day!

You can add which fields you want to preload and how deep to go. Check nested preloading.
In your case, you could do it like the below.
add User field to Account struct:
type Account struct {
Id uuid.UUID `gorm:"type:uuid;default:gen_random_uuid()" json:"id"`
Name string `json:"name"`
Balance float32 `json:"balance"`
UserId string `json:"user_id"`
User *User `json:"user"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
in your method:
var users []User
// Preload Account field inside User struct, and User field inside Account struct
err := db.Preload("Account.User").Find(&users).Error

Related

Prisma constraint not available

I`m using Prisma with NestJS and PostgreSQL
In my schema.prisma i have this
model User {
userId Int #id #default(autoincrement())
firstName String? #db.VarChar(25)
lastName String? #db.VarChar(25)
login String #unique #db.VarChar(60)
email String #unique
password String
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
role Role? #default(ADMIN)
createdUsers User[] #relation("createdBy")
createdBy User? #relation("createdBy", fields: [creatorId], references: [userId])
creatorId Int?
}
enum Role {
ADMIN
MANAGER
WAREHOUSE
USER
}
So when a make create request like this
{
login: "A",
email: "A",
password: "A"
}
it saves in DB - that`s ok. By after the same request i get this error "Unique constraint failed on the (not available)". So shouldn't there be a not unique column name instead of (not available) or that is ok case? Where am i wrong?
I was trying drop table Users and make different unique combs, don`t know what else i can do...
UPD:
async create(createUserDto: CreateUserDto) {
return this.prisma.user.create({
data: {
...createUserDto
}
})
}
export class CreateUserDto {
#IsNotEmpty()
login: string;
#IsNotEmpty()
#IsEmail()
email: string;
#IsNotEmpty()
#MinLength(6)
password: string;
}
UPD 2.0
Finally, moved to TypeORM, it is bug like #num8er mentioned
https://github.com/prisma/prisma/issues/10829
Ty for all the replies

How to write a migration to add not null in table field GOLANG

I want to alter a column in User Model
type User struct {
gorm.Model
Email string `gorm:"unique;type:varchar(50)"`
Password string
Active bool
FirstName string `gorm:"type:varchar(10)"`
LastName string `gorm:"type:varchar(10)"`
Age int
Gender bool `gorm:"type:boolean"`
MaritalStatus bool `gorm:"type:boolean"`
Address string `gorm:"type:varchar(10)"`
City string `gorm:"type:varchar(10)"`
State string `gorm:"type:varchar(10)"`
Country string `gorm:"type:varchar(10)"`
ContactNoOne string `gorm:"type:varchar(13)"`
ContactNoTwo string `gorm:"type:varchar(13)"`
}
I want to make Email field as not nullable. How to write migration for that?
add not null on tag gorm
type User struct {
...
Email string `gorm:"unique;type:varchar(50);not null"`
...
}
doc : https://gorm.io/docs/models.html
Edit your model, then us AutoMigrate
db.AutoMigrate(&User{})
Documentation: https://gorm.io/docs/migration.html

GORM Change time format in postgresql

I have a problem with time in postgresql table with generic GORM model
gorm.Model
with fields
type Model struct {
ID uint `gorm:"primary_key"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time `sql:"index"`
}
all dates in table have format 2020-04-21 22:05:07.067446
Please Can I change to timstamp(LONG) or something without .067446
Thanks for any Help
You can use BeforeCreate and BeforeUpdate hook for gorm.Model to manually set the value for the database.
Create BaseModel since you can't use type receiver for other package type.
type BaseModel struct {
gorm.Model
}
Then manually set the value CreatedAt and UpdatedAt without nanoseconds
func (b *BaseModel) BeforeCreate() (err error) {
b.CreatedAt = time.Unix(time.Now().Unix(), 0) // Calculate without nanosec
return
}
func (b *BaseModel) BeforeUpdate() (err error) {
b.UpdatedAt = time.Unix(time.Now().Unix(), 0) // Calculate without nanosec
return
}
And then use BaseModel in your DB Model
type Data struct {
BaseModel
Name string
}

how to make correctly has many associations in Golang with go

let say one teacher has many students and student only has one teacher, how to implement it on Gorm Golang ?
my opinion is
type Teacher struct {
gorm.Model
Name string
Student []Student
}
type Student struct {
gorm.Model
Name string
}
is those correct ?? and if not how to make it to be associated? and how about if we query it to create ? should I create another StudentID on it ?
type Teacher struct {
gorm.Model
Name string
}
type Student struct {
gorm.Model
Name string
TeacherId uint `gorm:"TYPE:integer REFERENCES teachers;index"`
}

Do I need to have two different objects to read and to write in my database using gorm (golang)?

gorm tell in the documentation that "Base model definition gorm.Model, including fields ID, CreatedAt, UpdatedAt, DeletedAt, you could embed it in your model, or only write those fields you want":
// Base Model's definition
type Model struct {
ID uint `gorm:"primary_key"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
}
// Add fields `ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt`
type User struct {
gorm.Model
Name string
}
// Only need field `ID`, `CreatedAt`
type User struct {
ID uint
CreatedAt time.Time
Name string
}
Following the documentation, I expect to have only one definition of User, so I create an object like that:
type User struct {
gorm.Model
ID uint
CreatedAt time.Time
Name string
}
But if I do a DB.CreateTable(&User{}), I get the following errors from postgres:
(pq: column "id" specified more than once)
(pq: column "created_at" specified more than once)
So I have to have two different objects :
type CreateUser struct {
gorm.Model
Name string
}
type RetrieveUser struct {
gorm.Model
ID uint
CreatedAt time.Time
Name string
}
So I can do a DB.CreateTable(&CreateUser{})
It is very ugly and I must be missing something, any idea?
Ok, just read the code behind gorm.Model and I got my answer.
type Model struct {
ID uint `gorm:"primary_key"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time `sql:"index"`
}
It means I just learned how inheritance works in go !