diff --git a/models/record.go b/models/record.go index d8dbff4b..c92fd53a 100644 --- a/models/record.go +++ b/models/record.go @@ -30,6 +30,8 @@ type Record struct { ignoreEmailVisibility bool // whether to ignore the emailVisibility flag for auth collections data map[string]any // any custom data in addition to the base model fields expand map[string]any // expanded relations + loaded bool + originalData map[string]any // the original (aka. first loaded) model data } // NewRecord initializes a new empty Record model. @@ -103,6 +105,15 @@ func (m *Record) Collection() *Collection { return m.collection } +// OriginalCopy returns a copy of the current record model populated +// with its original (aka. the initially loaded) data state. +func (m *Record) OriginalCopy() *Record { + newRecord := NewRecord(m.collection) + newRecord.Load(m.originalData) + + return newRecord +} + // Expand returns a shallow copy of the record.expand data // attached to the current Record model. func (m *Record) Expand() map[string]any { @@ -270,6 +281,11 @@ func (m *Record) FindFileFieldByFile(filename string) *schema.SchemaField { // Load bulk loads the provided data into the current Record model. func (m *Record) Load(data map[string]any) { + if !m.loaded { + m.loaded = true + m.originalData = data + } + for k, v := range data { m.Set(k, v) } diff --git a/models/record_test.go b/models/record_test.go index 86fc8b17..92cdd35b 100644 --- a/models/record_test.go +++ b/models/record_test.go @@ -331,6 +331,33 @@ func TestRecordCollection(t *testing.T) { } } +func TestRecordOriginalCopy(t *testing.T) { + m := models.NewRecord(&models.Collection{}) + m.Load(map[string]any{"f": "123"}) + + // change the field + m.Set("f", "456") + + if v := m.GetString("f"); v != "456" { + t.Fatalf("Expected f to be %q, got %q", "456", v) + } + + if v := m.OriginalCopy().GetString("f"); v != "123" { + t.Fatalf("Expected the initial/original f to be %q, got %q", "123", v) + } + + // Loading new data shouldn't affect the original state + m.Load(map[string]any{"f": "789"}) + + if v := m.GetString("f"); v != "789" { + t.Fatalf("Expected f to be %q, got %q", "789", v) + } + + if v := m.OriginalCopy().GetString("f"); v != "123" { + t.Fatalf("Expected the initial/original f still to be %q, got %q", "123", v) + } +} + func TestRecordExpand(t *testing.T) { collection := &models.Collection{} m := models.NewRecord(collection)