Определите новый тип:
type Data map[string]interface{}
И внедрите в них интерфейсы Valuer
и Scanner
, что позволяет преобразовать поле в значение для базы данных. и сканировал обратно в поле, соответственно:
// Value converts into []byte
func (d Data) Value() (driver.Value, error) {
j, err := json.Marshal(d)
return j, err
}
// Scan puts the []byte back into Data
func (d *Data) Scan(src interface{}) error {
source, ok := src.([]byte)
if !ok {
return errors.New("Type assertion .([]byte) failed.")
}
var i interface{}
if err := json.Unmarshal(source, &i); err != nil {
return err
}
*d, ok = i.(map[string]interface{})
if !ok {
return errors.New("Type assertion .(map[string]interface{}) failed.")
}
return nil
}
Затем вы можете определить свое поле в вашей модели следующим образом:
type User struct {
gorm.Model
Data Data `type: jsonb not null default '{}'::jsonb`
}
Используя базовый * Тип 1016 * тоже хорош, так как вы можете Unmarshal
/ Marshal
любой JSON в / из него.