Does AutoMigration() also give the NOT NULL attribute on the database side? - go

In GORM, does AutoMigration() also give the NOT NULL attribute on the database side?
Thanks in advance

The answer is: No
So if you do not define not null (using GORM field tags) to that particular field, GORM will not add NOT NULL constraint to the field on db side. Except for the primary key. By default, PK will be defined as NOT NULL field.
Way to define the field as NOT NULL in GORM:
type User struct {
...
Email string `gorm:"not null"` // NOT NULL
...
}
For more, see official documentation of GORM: Field Tags

Related

GORM not inserting foreign key with create

I am having issues with Go's GORM. When I am trying to save an entity to the DB with a model inside it, it does not save the foreign key with the owner model.
Below is my Models, The MySQL script and the way I save/create the model into the DB.
The error I am getting is: Field 'business_industry_id' doesn't have a default value
type Business struct {
gorm.Model
BusinessName string `json:"BusinessName" binding:"required" gorm:"column:business_name;type:varchar(100);unique;not null"`
BusinessIndustry Industry `json:"BusinessIndustry" binding:"required" gorm:"foreignkey:id"`
}
type Industry struct {
gorm.Model
Name string `json:"Name" gorm:"column:name;type:varchar(100);unique;not null"`
}
CREATE TABLE `industries`
(
id INT(6) AUTO_INCREMENT,
name VARCHAR(100) UNIQUE NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT current_timestamp,
deleted_at TIMESTAMP,
updated_at TIMESTAMP,
PRIMARY KEY (id)
);
CREATE TABLE `businesses`
(
id INT(6) AUTO_INCREMENT,
business_name VARCHAR(100) NOT NULL UNIQUE,
business_industry_id INT(6) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT current_timestamp,
deleted_at TIMESTAMP,
updated_at TIMESTAMP,
PRIMARY KEY (id),
FOREIGN KEY (business_industry_id) REFERENCES industries (id)
);
err := bs.database.Create(business).Error
I tried remove the Grom attributes from the models, to let the framework figure it out on it's own, but I got the same error.
When I inspect the model, the industry have id of 3 (Because I resolved it earlier on myself) and after I do the save, the ID is 0.
But when I removed the attributes, the id was 3 after the save as well, but the same error occurred.
I know what the error message mean, because the sql message that is logged, doesn't actually insert the 3 into the business_industry_id field. What I don't know is, why it doesn't insert it.
I'm fairly certain you have to include the foreign key, you can't just have the associated model (see http://gorm.io/docs/has_many.html). So you need to do:
type Business struct {
gorm.Model
BusinessName string `json:"BusinessName" binding:"required" gorm:"column:business_name;type:varchar(100);unique;not null"`
BusinessIndustryID uint
BusinessIndustry Industry `json:"BusinessIndustry" binding:"required" gorm:"foreignkey:id"`
}

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"`
}

GraphQL non-nullable field nested in nullable field

I have a GraphQL query that returns a set of notifications. The "creator" field does not appear in every notification which is a problem because it is of type "User" and User has an "id" field that is non-nullible. Is it possible to have non-nullible fields nested in nullable ones?
{
myNotifications {
id
title
message
image
creator {
id
full_name
}
}
}
A non-null field will only be validated if it is resolved. If the parent field resolve to null, any children fields will not be resolved, and so the validation never happens. In other words, it's perfectly fine to have a non-null field whose parent field is nullable.

Go-Gorm: will the foreignkey be auto-populated when I set an object?

In the documentation we have this example:
type User struct {
gorm.Model
Name string
}
// `Profile` belongs to `User`, `UserID` is the foreign key
type Profile struct {
gorm.Model
UserID int
User User
Name string
}
If I do something like profile.User = &user, will that automatically populate the UserID field? Is it recommended to set both? Like:
profile.User = &user
profile.UserID = &user.ID
Or is that pointless? Furthermore, could I alternatively just set the UserID field and ignore the User field entirely?
If I do something like profile.User = &user, will that automatically populate the UserID field?
Just writing profile.User = &user will not populate the UserID field. Once you add the profile to the database. gorm will automatically populate the foreign key.
Is it recommended to set both?
Nope. In fact, you should not set the UserID yourself. This answers the last question as well.

Gorm - upgrading columns constraint with migration

How do you perform a Migration with gorm? For example, I need to add a constraint to a column. I changed my model (simplified example below), but the AutoMigrate method, according to the docs, will not change column's constraints.
How do you achieve it then? I cannot find anything useful in the docs
Starting model:
type User struct {
gorm.Model
Name string
}
I would like to update it like this:
type User struct {
gorm.Model
Name string `gorm:"not null"`
}
When adding a not null constraint, then a default value will also need to be added for when the existing records do not meet the new criteria. The definition could be something like:
type User struct {
gorm.Model
Name string `gorm:"not null;default:'fillertext'"`
}
As #putu said, ALTER TABLE will certainly work, but you would still need to add a default value initially to ensure the non-comforming rows meet the new requirements. Once this has been done you can remove the default value if you desire and the migration will work as intended from that point on.

Resources