GO GORM foreign key constraint is not created - go

I'm having issues with creating foreign key constraint for the Belongs to relationship.
A struct containing foreign key:
type Summary struct {
Id string `gorm:"primaryKey"`
OwnerId *string `gorm:"foreignKey:OwnerId references:Id;not null"`
Title string
}
Struct to which summary belongs to:
type Owner struct {
Id string `gorm:"primaryKey"`
Name string
}
It creates the tables in SQL without a problem but SQL schema doesn't contain foreign key constraint in the summary table on the owner_id column and therefore Summary can be inserted when an owner doesn't exist.

What eventually worked but not the perfect solution in my opinion is referencing the Owner struct inside Summary like so:
type Summary struct {
Id string `gorm:"primaryKey"`
OwnerId string
Owner Owner `gorm:"foreignKey:OwnerId"`
Title string
}
I wonder if it's the only way to do so

What version of gorm are you using? If you are on v1 of the library, try switching to v2. I experienced similar issues while using v1 of the library.
v1 dependency download
go get -u github.com/jinzhu/gorm
v2 dependency download
go get -u gorm.io/gorm

Related

many to many in gorm v2 error on foreign key

I'm finding it difficult to define many to many relationship using Gorm in following cases
features(feature_id, name, slug)
operations(operation_id, name, slug)
feature_operations(feature_id, operation_id)
type Feature struct {
FeatureID int64 `gorm:"primaryKey;column:feature_id" json:"feature_id"`
Name string `validate:"required" json:"name"`
Slug string `json:"slug"`
Status string `json:"status"`
Operations []Operation `gorm:"many2many:feature_operations;foreignKey:feature_id"`
appModels.BaseModel
}
When using feature_id, I get error
column feature_operations.feature_feature_id does not exist
When using id, I get error
invalid foreign key: id
Looks like you are not using the convention that gorm suggests where you name your primary key columns just id
so in your case your foreignKey should be the name of the field and you also need to use References to specify column that you want to reference. See the example here:
https://gorm.io/docs/many_to_many.html#Override-Foreign-Key
What you need is this:
type Feature struct {
FeatureID int64 `gorm:"primaryKey;column:feature_id"`
Name string
Slug string
Operations []Operation `gorm:"many2many:feature_operations;foreignKey:FeatureID;References:OperationID"`
}
type Operation struct {
OperationID int64 `gorm:"primaryKey;column:operation_id"`
Name string
Slug string
}
After this the join table will be FEATURE_OPERATIONS with two columns FEATURE_FEATURE_ID AND OPERATION_OPERATION_ID
If you dont like the redundant column names then you need to use the two additional attributes joinForeignKey and joinReferences to choose your own names for the columns like so:
gorm:"many2many:feature_operations;foreignKey:FeatureID;joinForeignKey:FeatureID;References:OperationID;joinReferences:OperationID"
All this extra work is needed because your primary keys are FEATURE_ID and OPERATION_ID instead of just ID
If you can rename the column to follow the convention, you will notice life is much easier with gorm

How to permanently delete associations in GORM

I want to know how to permanently delete associations in GORM. I tried all examples shown in the documentation but I cannot get associations to become permanently deleted. For example, I am confused by GORM's documentation on deleting and clearing associations, which explicitly says: won't delete those objects from DB. (I don't understand what it means to delete objects without deleting them from the database.)
I have similar structs:
type User struct {
gorm.Model
City string `sql:"type:varchar(255);not null"`
Cards []Card `gorm:"foreignKey:UserID;constraint:OnDelete:CASCADE"`
}
type Card struct {
ID uint `gorm:"primary_key"`
UserID uint `gorm:"column:user_id"`
}
I want to execute the following SQL query in GORM form:
DELETE c
FROM cards c
JOIN users u ON c.user_id = u.id
WHERE u.name = `Madrid`
gorm.Model is including a DeletedAt field. So on deletion, this will be set to the current date, the record won't be removed from the database, but will not be findable with normal query methods. They call that "soft delete".
In order to delete the record permanently you have to use Unscoped, like:
db.Unscoped().Delete(&order)
Source: https://gorm.io/docs/delete.html

Is there a way to add a custom column when we create a many2many association in gorm?

I want to know 2 things
I got the following structs from a similar question.
// models/school.go
type School struct {
ID int `gorm:"primary_key"`
Name string `gorm:"not null"`
Accreditations []Accreditation `gorm:"many2many:school_accreditation;"`
}
type Accreditation struct {
// "accreditation" table
ID int `gorm:"primary_key"`
Name string
Description string
}
So, by default this will create a school_accreditation table with 2 columns:
one will have School's ID
other will have Accreditation's ID
My questions:
What is the most efficient way to add another column to the school_accreditation table?
Let's say I want to have the Name field of Accreditation in the school_accreditation table.
2.1) How do I achieve this eg: school_accreditation will have school_id, accreditation_id, accreditation_name
For the 1st question,
It seems the only way of doing it by defining the SchoolAccreditation model & adding fields to it.
Also, it gives me more control over the relationship.
For the 2nd question, I am yet to find a way if there is any!
bost
For the 2nd,
You have to manually get the name from Accreditation & then add it to the column via the defined SchoolAccreditation model.

Getting a "Duplicate column name 'id'" error when using gorm's AutoMigrate [duplicate]

While creating primary key from gorm model it return with error “duplicate column name: “id””
my model looks like
type User struct {
gorm.Model
Id string gorm:"primary_key;"
FirstName string
LastName string
}
any idea what is the issue with above model
Gorm uses ID as the primary key by default. It is part of the gorm.Model you are embedding.
When embedding the gorm.Model, you should leave ID out as gorm already includes it. The alternative is to remove the embedded gorm.Model and specify ID yourself.
To quote the gorm conventions page:
gorm.Model is a basic GoLang struct which includes the following
fields: ID, CreatedAt, UpdatedAt, DeletedAt.
It may be embeded into your model or you may build your own model
without it.
The reasons this fails on schema creation as opposed to compilation is that a lot of databases (CockroachDB included) do case insensitive checking unless you quote the object names (Id matches id, but "Id" does not). This results in two separate column names that match when compared with case insensitivity.

Issue while creating primary key from gorm model

While creating primary key from gorm model it return with error “duplicate column name: “id””
my model looks like
type User struct {
gorm.Model
Id string gorm:"primary_key;"
FirstName string
LastName string
}
any idea what is the issue with above model
Gorm uses ID as the primary key by default. It is part of the gorm.Model you are embedding.
When embedding the gorm.Model, you should leave ID out as gorm already includes it. The alternative is to remove the embedded gorm.Model and specify ID yourself.
To quote the gorm conventions page:
gorm.Model is a basic GoLang struct which includes the following
fields: ID, CreatedAt, UpdatedAt, DeletedAt.
It may be embeded into your model or you may build your own model
without it.
The reasons this fails on schema creation as opposed to compilation is that a lot of databases (CockroachDB included) do case insensitive checking unless you quote the object names (Id matches id, but "Id" does not). This results in two separate column names that match when compared with case insensitivity.

Resources