اكثر شغلة مزعجة في Realm انها ماتدعم Cascading Deletes
بمعنى اذا عندك Database فيها Parent و Child لما تحذف الـ Parent المفروض يحذف الـ Child معاه
هذا الامر في اغلب الـ Database الا Realm
مثال للمشكلة بإستخدام Realm ، عندي هذا الـ Model
عباره عن جدول Contact وبداخله جدول Address
حسب الي ذكرته سابقا في ميزة الـ Cascading Deletes
البديهي اذا حذفت Contact المفروض يحذف الـ Address
لكن في Realm ماراح يصير هذا الشي!
class Contact: Object {
@objc dynamic var _id = ObjectId.generate()
@objc dynamic var name = ""
@objc dynamic var address: Address?
override static func primaryKey() -> String? {
return "_id"
}
override init() {
super.init()
}
convenience init(name: String, address: Address) {
self.init()
self.name = name
self.address = address
}
}
class Address: Object {
@objc dynamic var country: String?
@objc dynamic var city: String?
override init() {
super.init()
}
init(country: String? = nil, city: String? = nil) {
self.country = country
self.city = city
}
}
مثال اضفت contact و address
وبعدها حذفت الـ contact
النتيجة انحذف الـ Contact لكن الـ Address لازال متوفر !
struct ContentView: View {
let realm = try! Realm()
var body: some View {
VStack {
Text("Demo")
Button {
let contact = Contact()
let newContact = Contact(name: "Ahmad", address: Address(country: "Saudi Arabia", city: "Jeddah"))
try! realm.write {
realm.add(newContact)
}
} label: {
Text("Add")
}
Button {
let ahmadContact = realm.objects(Contact.self)
guard let ahmadContact = realm.objects(Contact.self)
.filter("address.city = %@", "Jeddah")
.first,
let ahmadContactAddress = ahmadContact.address else {
print("Could not find Ahmad address!")
return
}
try! realm.write {
// Delete the instance from the realm.
realm.delete(ahmadContact)
}
} label: {
Text("Delete")
}
}
.padding()
}
}


في النسخ السابقة لحل هذه المشكلة
يتوجب عليك حذف جميع الـ Child وبعدها تحذف الـ Parent
Button {
// delete child then delete parent
if let contactToDelete = realm.objects (Contact.self).filter("name = 'Ahmad'").first {
try! realm.write {
if let addressToDelete = contactToDelete.address {
realm.delete(addressToDelete)
}
realm.delete (contactToDelete)
}
}
} label: {
Text("Delete")
}
النتيجة انحذف الـ Child و الـ Parent

في السابق كانت هذه الطريقة ولسنوات كانت مزعجة
لكن واخيرا في نسخة رقم 10 التي صدرت في بداية السنة الماضية 2022 Realm
صارات تدعم Cascading Deletes !
هذه الميزة من 2017 نطالب بإضافتها!
عموما الطريقة جدا بسيطة ومختصره وتحتاج خطوتين فقط
الخطوه الاولى : تحتاج تبدل الـ Object الى EmbeddedObject لكل الـ Child
الخطوة الثانية: لازم كل المتغيرات تكون نوعها Optional تحديث للـ Models
فالتغيير الوحيد هو تغير الـ Address من Object الى EmbeddedObject
class Address: EmbeddedObject {
@objc dynamic var country: String? = nil
@objc dynamic var city: String? = nil
override init() {
super.init()
}
init(country: String? = nil, city: String? = nil) {
self.country = country
self.city = city
}
}
الان فقط احذف الـ Parent وراح ينحذف الـ Child معاه
بمعنى حذف Contact راح يحذف Address بدون ما تحتاج تعمل اي حاجة
ولاحظ شكل الجدول تغير address ماصار موجود في الجهة اليسرى وصار address مكتوب جنبه (Embedded)
تقدر تضغط عليه لفتح جدول الـ Address


معلومة إضافية ايضا في النسخة الـ 10 Realm
اصبحت ايضا تدعم نوع Decimal128 بمعنى تقدر تضيف متغير من نوع Float , CGFloat الخ .. ،
بدون ما تحتاج تحولهم الى Double وتفقد بعض الارقام
