You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Realm现有模型添加关联:iOS应用MedicationObject数据丢失问题咨询

Hey there! Let's figure out why your MedicationObject data is getting wiped out (leaving only the last entry) when you save MedicationRecording instances. This is a common pitfall with Realm relationships, so let's break down the likely issues and fixes.

First, Let's Confirm Correct Realm Relationship Setup

For a many-to-one association (one MedicationObject has multiple MedicationRecordings), your models need to follow Realm's rules for bidirectional relationships. Here's the proper structure:

import RealmSwift

// 用药信息对象("one" side of the relationship)
class MedicationObject: Object {
    // Use a unique, non-repeating primary key (UUID is ideal)
    @Persisted(primaryKey: true) var id: String = UUID().uuidString
    @Persisted var name: String
    @Persisted var dosage: String
    // List to hold all related medication recordings
    @Persisted var recordings = List<MedicationRecording>()
}

// 用药记录对象("many" side of the relationship)
class MedicationRecording: Object {
    @Persisted(primaryKey: true) var id: String = UUID().uuidString
    @Persisted var recordTime: Date
    // Reference back to the parent MedicationObject
    @Persisted var medication: MedicationObject?
}

Why Your Data Is Getting Lost (Common Mistakes)

The most likely culprits are:

  • Repeating primary keys on MedicationObject: If you used a non-unique field (like name) as the primary key, saving a new MedicationObject with the same name would overwrite the existing one—including its entire recordings list.
  • Creating a new MedicationObject every time you save a recording: Instead of reusing the existing object reference, you're making a fresh one each time, which disconnects old recordings from their parent.
  • Accidental overwrites in write transactions: Using realm.add(medObject, update: true) with a duplicate primary key replaces the entire existing object, not just updates its properties.

The Fix: Reuse Existing Medication Objects

When saving a new recording, first check if the corresponding MedicationObject already exists. If it does, reuse it; if not, create a new one. Here's a corrected save method:

func saveMedicationRecording(
    existingMedId: String? = nil,
    medName: String,
    medDosage: String,
    recordTime: Date
) {
    let realm = try! Realm()
    
    do {
        try realm.write {
            var targetMedication: MedicationObject
            
            // 1. Try to fetch an existing MedicationObject
            if let medId = existingMedId, 
               let existingMed = realm.object(ofType: MedicationObject.self, forPrimaryKey: medId) {
                targetMedication = existingMed
            } else {
                // 2. Create a new MedicationObject if none exists
                targetMedication = MedicationObject()
                targetMedication.name = medName
                targetMedication.dosage = medDosage
                realm.add(targetMedication)
            }
            
            // 3. Create and link the new recording to the medication
            let newRecording = MedicationRecording()
            newRecording.recordTime = recordTime
            newRecording.medication = targetMedication
            
            // Optional: Add the recording directly to the medication's list (Realm syncs both ways)
            targetMedication.recordings.append(newRecording)
            
            realm.add(newRecording)
        }
    } catch {
        print("Failed to save recording: \(error.localizedDescription)")
    }
}

Key Takeaways to Avoid Future Issues

  • Stick to unique primary keys: Use UUIDs for MedicationObject (and MedicationRecording) to prevent accidental overwrites. Never use fields like name that can repeat.
  • Reuse object references: Always fetch existing MedicationObjects before creating new ones—this keeps all related recordings linked to the same parent.
  • Understand Realm's relationship sync: Either set newRecording.medication = targetMedication or append the recording to targetMedication.recordings; Realm automatically syncs both directions, so you don't need to do both (though it won't hurt).

内容的提问来源于stack exchange,提问作者Osian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:24:37