首页 > 解决方案 > Many2Many JoinTable 中的自定义字段

问题描述

我有一个带有自定义 JoinTable 的模型:

type Person struct {
  ID        int
  Name      string
  Addresses []Address `gorm:"many2many:person_addresses;"`
}

type Address struct {
  ID   uint
  Name string
}

type PersonAddress struct {
  PersonID  int
  AddressID int
  Home      bool
  CreatedAt time.Time
  DeletedAt gorm.DeletedAt
}

Home创建新字段时如何为字段赋值Person

标签: mysqlgogo-gorm

解决方案


方法一

从我在文档中看到的内容来看,这是您目前可能执行此操作的一种干净方式:

DB.SetupJoinTable(&Person{}, "Addresses", &PersonAddress{})

addr1 := Address{Name: "addr1"}
DB.Create(&addr1)

addr2 := Address{Name: "addr2"}
DB.Create(&addr2)

person := Person{Name: "jinzhu"}
DB.Create(&person)

// Add an association with default values (i.e. Home = false)
DB.Model(&person).Association("Addresses").Append(&addr1)

// Add an association with custom values
DB.Create(&PersonAddress{
    PersonID:  person.ID,
    AddressID: addr2.ID,
    Home:      true,
})

在这里,我们使用实际的连接表模型来插入包含我们想要的值的行。

我们还可以过滤关联查询:

addr := Address{}
// Query association with filters on join table
DB.Where("person_addresses.home = true").
    Model(&person).
    Association("Addresses").
    Find(&addr)

方法二

除了上面的代码之外,这是一种更神奇的方式,通过(ab)使用Context将值传递给钩子:BeforeSaveSetupJoinTable

func (pa *PersonAddress) BeforeSave(tx *gorm.DB) error {
    home, ok := tx.Statement.Context.Value("home").(bool)
    if ok {
        pa.Home = home
    }
    return nil
}

// ...

DB.WithContext(context.WithValue(context.Background(), "home", true)).
    Model(&person).
    Association("Addresses").
    Append(&addr2)

这种方法对我来说感觉很恶心,但它确实有效。


推荐阅读