Wessel van der Linden
Wessel van der Linden

Reputation: 2622

GORM update associations by ids only

In GORM, I want to be able to update a model's associations by only using a slice of IDs.

For example, when I have the following constructs:

type Library struct {
    gorm.Model
    Books []*Book
}

type Book struct {
    ID          uint
    Library     *Library
    LibraryID   uint
}

I can update the "Books" relation like so:

books := []*Book{} // filled somewhere else
library := &Library{} // filled somwhere else

library.Books = books
db.Save(library)

or like so:

books := []*Book{} // filled somewhere else
library := &Library{} // filled somwhere else

db.
    Model(library).
    Association("Books").
    Replace(books)

Both ways I need to have a slice of Books, but I only have a slice of IDs. I can of course load the books first, and pass that to the Replace function:

var ids []uint
books := []*Book{}
db.Find(&books, ids)
db.Model(&Library{}).Association("Books").Replace(books)

But I don't want to do that, since I know it's possible to send a single query to update the association.

So how can I do this?

Upvotes: 1

Views: 2952

Answers (1)

Ezequiel Muns
Ezequiel Muns

Reputation: 7742

You can create the []*Book from the IDs like this:

var ids []uint
books := make([]*Book, len(ids))
for i, id := range ids {
   books[i] = &Book{ID: id}
}

Now you will have a slice of Books with only IDs, but that's all that gorm needs in order to fill the association:

db.
    Model(library).
    Association("Books").
    Replace(books)

You will be dependant on any database-level foreign key constraints to make sure the IDs you're replacing are actually valid book IDs.

Upvotes: 1

Related Questions