Как выполнить запрос «многие ко многим»

# #go #go-gorm

Вопрос:

Я пытаюсь понять, как использовать GORM для выполнения запросов по элементам со многими отношениями 2many, но я действительно заблудился.

У меня есть следующая модель базы данных:

 type Asset struct {
    gorm.Model
    Id             uint            `gorm:"primaryKey"`
    MachineUID     string          `gorm:"type:varchar(128)" json:"machine_uid"`
    AssetToken     string          `gorm:"uniqueIndex;type:varchar(128)"`
    CommandQueries []*CommandQuery `gorm:"many2many:command_asset;"`
}


type CommandQuery struct {
    gorm.Model
    Id      uint     `gorm:"primaryKey"`
    UUID    string   `gorm:"type:varchar(128)" json:"uuid"`
    CmdType int      `json:"cmdtype"`
    CmdArgs string   `gorm:"type:varchar(128)" json:"cmdargs"`
    Assets  *[]Asset `gorm:"many2many:command_asset;"`
    Active  bool
}
 

Во-первых, я успешно пытаюсь извлечь актив из токена с помощью чего-то подобного:

 token := "test-token"
var result Asset
db.Where("asset_token = ?", token).First(amp;result)

if result.Id == 0 {
    return fmt.Errorf("Asset cannot be found in database")
}

 

Но для этой возвращенной структуры я хотел бы повторно просмотреть все объекты CommandQuery, где:

  • этот ресурс находится в CommandQuery.активы
  • Где CommandQuery.active = true

Я перепробовал много вещей, но ничего не работает, любая помощь будет признательна.

Ответ №1:

Если я правильно понял, вы хотите загрузить фрагмент CommandQuery объектов, и эти объекты должны содержать только активы, которые asset_token должны быть равны переданному вами токену. Кроме того, возвращайте только CommanQuery те объекты, которые есть active=true .

Если это так, то это можно сделать так:

 token := "test-token"
var list []CommandQuery{}
tx := db.Preload("Assets", func (gdb *gorm.DB) *gorm.DB{
           return gdb.Where("asset_token = ?", token)
         }).
         Where("active = ?", true).Find(amp;list)

if tx.Error == nil {
    return nil, tx.Error
}

return *list, nil
 

Короче говоря, пользовательская предварительная загрузка используется для загрузки ресурсов в объекты командных запросов.

Комментарии:

1. большое вам спасибо, это было то, что я хотел сделать. Еще один вопрос: можно ли из среза CommandQuery избежать возврата поля «активы» непосредственно из запроса gorm?

2. что вы подразумеваете под «избегать возврата активов»?

3. Когда я возвращаю фрагмент командного запроса, я не хочу, чтобы пользователь видел все остальные, для которых был создан этот запрос. Я могу вручную очистить поле «активы» каждой структуры, но мне интересно, можно ли не сопоставлять это поле с этим конкретным запросом

4. Если вы исключите Preload функцию из этого запроса, ни один из ресурсов не будет заполнен.