Hongli
Hongli

Reputation: 18924

How to reference a composite primary key in GORM?

Golang's GORM library supports composite primary keys. But how to reference them from related models?

For example, suppose I have a User and a Note model:

type User struct {
    OrganizationID uint   `gorm:"primaryKey; not null"`
    Name           string `gorm:"primaryKey; not null"`
}

type Note struct {
    ID             uint   `gorm:"primaryKey; not null"`
    OrganizationID uint   `gorm:"not null"`
    UserName       string `gorm:"not null"`
    User           User
}

The auto migrator creates the notes table like this, which fails:

CREATE TABLE "notes" ("id" bigserial NOT NULL,"user_name" text NOT NULL,"organization_id" bigint NOT NULL,PRIMARY KEY ("id"),
CONSTRAINT "fk_notes_user" FOREIGN KEY ("user_name") REFERENCES "users"("name"))

But I want it to do this instead:

CONSTRAINT "fk_notes_user" FOREIGN KEY ("user_name", "organization_id") REFERENCES "users"("name", "organization_id")

How can I accomplish this?

Upvotes: 4

Views: 9635

Answers (1)

Mafor
Mafor

Reputation: 10681

You can use ForeignKey and References tags. They are mentioned in the docs, although in the reversed (One-to-Many) context.

type User struct {
    OrganizationID uint   `gorm:"primaryKey; not null"`
    Name           string `gorm:"primaryKey; not null"`
}

type Note struct {
    ID             uint   `gorm:"primaryKey; not null"`
    OrganizationID uint   `gorm:"not null"`
    UserName       string `gorm:"not null"`
    User           User   `gorm:"ForeignKey:OrganizationID,UserName;References:OrganizationID,Name"`
}

AutoMigrate will generate the following sql:

CREATE TABLE `users` (`organization_id` integer NOT NULL,`name` text NOT NULL,PRIMARY KEY (`organization_id`,`name`))

CREATE TABLE `notes` (`id` integer NOT NULL,`organization_id` integer NOT NULL,`user_name` text NOT NULL,PRIMARY KEY (`id`),CONSTRAINT `fk_notes_user` FOREIGN KEY (`organization_id`,`user_name`) REFERENCES `users`(`organization_id`,`name`))

Upvotes: 10

Related Questions