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 (likename) as the primary key, saving a newMedicationObjectwith the same name would overwrite the existing one—including its entirerecordingslist. - Creating a new
MedicationObjectevery 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(andMedicationRecording) to prevent accidental overwrites. Never use fields likenamethat 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 = targetMedicationor append the recording totargetMedication.recordings; Realm automatically syncs both directions, so you don't need to do both (though it won't hurt).
内容的提问来源于stack exchange,提问作者Osian
相关产品推荐
相关产品推荐

