Does GORM support attibutes of many to many relationships? - go

Using the gorm.io library, how would I implement a many to many relationship, where the relationship itself has attributes?
Example:
Without the attribute I would do it something like this, but I can't find a solution to my Problem in the GORM docs.
type Recipe struct {
gorm.Model
Name string
Ingredients []Ingredient `gorm:"many2many"`
}
type Ingredient struct {
gorm.Model
Name string
}

Related

Should I explicitly create a relation symmetrical to "Belongs To" or "Has Many"?

I am new to ORM (and GORM) so apologies if this is an obvious question, but it does not seem to be covered by the documentation.
I will be using the examples from the documentation as a base to my questions
Question 1: Belongs To
// `User` belongs to `Company`, `CompanyID` is the foreign key
type User struct {
gorm.Model
Name string
CompanyID int
Company Company
}
type Company struct {
ID int
Name string
}
A User belongs to one Company only → this is handled by the code
above
A Company has many User → is this implied by the code
above? Or should I add somehow a relation O2M in Company?
Question 2: Has Many
// User has many CreditCards, UserID is the foreign key
type User struct {
gorm.Model
CreditCards []CreditCard
}
type CreditCard struct {
gorm.Model
Number string
UserID uint
}
A User has 1+ CreditCard→ this is handled by the code
A CreditCard can belong to several users (say, a shared family CC) → is it implied? (if not: how to set up the O2M relationship).
Or is it, instead, a case where a CreditCard is explicitly configured to belong to only one user?
Q1: Based on how you defined your structs, you don't need an explicit O2M relationship in the Company struct, but when loading Company details, if you want to load all users that are assigned to that specific company, you need to add that field as well. It will need an additional function call like Preload or Joins, but you shouldn't need an explicit definition of this relationship.
type Company struct {
ID int
Name string
Users []User
}
Q2: The way the relationship is defined now, it is configured so that a CreditCard belongs to only one user. If you want a many2many relationship, you need to specify the relation table. There is more documentation on it here, but it should look something like this:
type User struct {
gorm.Model
CreditCards []CreditCard `gorm:"many2many:users_creditcards"`
}
type CreditCard struct {
gorm.Model
Number string
}

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.

One-to-many recursive relationship in GORM

I need to have an Organization which have relation to parent one. Something like this:
type Organization struct {
gorm.Model
Parent *Organization `gorm:"ForeignKey:ParentId"`
Name string `gorm:"size:30"`
Description string `gorm:"size:100"`
}
I want to have ParentId field which will be referenced to id field in the same table. But as I see there is no field and relation.
How can I fix it ?
I have solved it like this, but I am not sure that it is a correct way:
type Organization struct {
gorm.Model
Parent *Organization
ParentId int `gorm:"TYPE:integer REFERENCES organizations"`
Name string `gorm:"size:30"`
Description string `gorm:"size:100"`
}

Entity association to itself with one-to-many relationships

I use GORM to build model associations in Golang and I have a struct named Category. A category can have many children categories and it may have a parent category:
type Category struct {
Name string `json:"name"`
Parent Category `json:"parent_category"`
ParentGroupID uint `json:"parent_group_id"`
Children []Category `json:"children_categories"`
}
For this struct, I got an error for Invalid recursive type Category. I checked the GORM documentation but did not find anything helpful there. Any ideas how to model this kind of relation with GORM?
You must declare Parent as *Category (a pointer to Category) instead of Category.
type Category struct {
Name string `json:"name"`
Parent *Category `json:"parent_category"`
ParentGroupID uint `json:"parent_group_id"`
Children []Category `json:"children_categories"`
}
How does compiler know what the size of Parent is. A pointer's size is known, but how big is something that contains itself? (And the inner struct contains itself as well, as does the inner inner struct, and so on.)
Reference: https://stackoverflow.com/a/8261789/4794989

Resources