How to create self-referenced association field - go

I'm trying to create self-reference field using gorm:
type Post struct {
ID uint `gorm:"primary_key" json:"id"`
Post *Post `json:"post" xml:"post" sql:"default:null"`
}
db.AutoMigrate(&Post{})
Column post_id is not created in DB. Tried several struct field names, no luck.
Which is the correct way to handle self-refrenced associations?
Thank you.

The Gorm magic isn't in the association (foreign key) part but in the data part.
Gorm will do the sql joins to retrieve the related Post row based on PostID It will then store that data in the nested Post field in Post.
If you only provide Post without PostID Gorm will do nothing as there is no foreign key for it to work with.
type Post struct {
ID uint `gorm:"primary_key" json:"id"`
Post *Post `json:"post" xml:"post" sql:"default:null"`
PostID uint `json:"post_id" xml:"post_id"`
}
db.AutoMigrate(&Post{})

Related

Gorm not giving correct inserted record's primary key ID

I am using GORM with GO.
I have an entity User
type User struct {
Id int `json:"id" gorm:"primaryKey;autoIncrement"`
Name string `json:"name"`
gorm.Model
}
My Create record code is
user := User{}
user.Name = "Afzal"
DB.Create(&user)
Now as per Doc user.ID should return inserted data's primary key
But it's returning 0 which is the default value when struct User was initialized.
User.Id will have the correct value, because you've added that field and tagged it as being the primary key. user.ID actually accesses user.Model.ID. This, too, has the primaryKey tag, but it's superseded by the Id field on your User type.
You've embedded the gorm.Model type (as per the docs, I imagine), but that means your User type actually looks like this:
User{
Id int
Name string
gorm.Model{
ID uint `gorm:"primarykey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt DeletedAt `gorm:"index"`
}
}
So when you look at user.ID, you're accessing the embedded ID field. Either check the Id field (lower-case d), or remove the Id field you've added, and rely on the ID from the embedded Model.
If you do want to keep your own Id field, I think the gorm.Model is right to make it a uint. If you're needing to faff around with negative ID elements in your data, you're probably doing something wrong... I've seen negative ID's being used, but every time I saw it happen, it was some absolutely horrible hack.

One-to-many relation need to define a valid foreign key error

I want to make a webapp and I have a simple data model with a one to many relation. I tried sticking to the documentation of gorm and from my understanding this should work:
package dbModels
import "gorm.io/gorm"
type Post struct {
gorm.Model
Text string
Likes int
Comments []Comment
}
type Comment struct {
gorm.Model
Text string
Likes int
PostID uint
}
I'm migrating these models like that:
db.AutoMigrate(&dbModels.Post{}, &dbModels.Comment{})
Then I want to put this object in post:
func (r *mutationResolver) CreatePost(ctx context.Context, input model.PostInput) (*model.Post, error) {
var items []*model.Comment
post := model.Post{
Text: input.Text,
Likes: 0,
Comments: items,
}
r.DB.Create(&post)
return &post, nil
}
however I get the following error:
2021/01/31 11:23:01 /home/felix/Projekte/GoReact/server/graph/schema.resolvers.go:21 invalid field found for struct github.com/blamefelix/TwitterClone/graph/model.Post's field Comments, need to define a valid foreign key for relations or it need to implement the Valuer/Scanner interface
I don't really understand what I'm doing wrong. From the gorm documentation I thought the relation would get managed by gorm if I put it like that? My suspicion is, that I put the wrong data in?
So I've managed to fix it by using the same model for graphql and gorm. The problem must have been that I've pased the wrong data into the db create function

Defining Belongs To relation for anonymous field using GORM

I wanted to create relationnal database structure in a using the go package Gorm.
I wanted to add foreign keys to my structure, it works perfectly on regular field, but it does not seem to work when I want to make foreign key for anonymous fields.
Here is some simplified code to demonstrate my case
type StructA struct {
gorm.Model
SimpleFieldID int // appears in database as foreign key
SimpleField StructB
TranslationID int // appears in database as a regular int
Translation
}
type StructB struct {
gorm.Model
SomeField string
SomeOtherField string
}
type Translation struct {
gorm.Model
En string
Fr string
}
I wanted to have anonymous field in the first place to be able to call some GetName() method on any object that has the Translation attribute.
I found this question, but the given anwser was for the has-one relation, where I want to use a belongs-to relation.

Join table with non-primary key in GORM

I am trying to retrieve the information of an author based on a field in BookData that is not a primary key. Below you can see I have AuthorId in my BookData table and I am trying to get the author based on that AuthorId even though it is not the primary key. It seems GORM does not support this type of join, is there a way to do this?
You can also see below that I am able to properly get the PublisherProperty information because it's foreign key is BookData's primary key. I am just wondering how to do it if it not the primary key. Thanks in advance!
type BookData struct {
Id string `gorm:"primary_key;column:book_id"`
AuthorId string `gorm:"column:author_id"`
Author AuthorData `gorm:"foreignkey:AuthorId"`
PublisherProperty []PublisherProperty `gorm:"foreignkey:Id"`
}
type AuthorData struct {
Id string `gorm:"primary_key;column:author_id"`
Name string `gorm:"column:author_name"`
}
type PublisherProperty struct {
Id string `gorm:"primary_key;column:book_id"`
PublisherId string `gorm:"primary_key;column:publisher_id"`
PublisherTxt string `gorm:"column:publisher_txt"`
}

Foreign key on source struct?

I'm starting with Gorm and trying to model the following:
type MyLink struct {
gorm.Model
Title string
Url string
}
// group of links under a single title
type MyLinkSection struct {
gorm.Model
Title string
Links []MyLink
}
type MyPage struct {
gorm.Model
PageUrl MyLink
Artists []MyLinkSection
}
As you can see I want to be able to refer to the same struct, MyLink as both a foreign keyed object from MyPage but also as a one-to-many from MyLinkSection.
It seems I have to declare the foreign key ID in MyLink which would seem to make this not possible.
Is there any way of setting up tables like this? With a normal DB I'd just have a field in MyPage called my_link_id, with something similar for MyLinkSection.
It seems it is possible to specify forward relations:
PageUrl MyLink `gorm:"ForeignKey:PageUrlId"`
PageUrl Id uint

Resources