user12329049
user12329049

Reputation:

How can I delete a realm parent object along with all of its child objects?

class Days : Object {
        @objc dynamic var weekday : String = ""

        let workout = List<Workouts>()
    }

class Workouts : Object {
    @objc dynamic var title : String = ""
    var parentDay = LinkingObjects(fromType: Days.self, property: "workout")

    let exercise = List<Exercises>()
}

class Exercises : Object {
    @objc dynamic var exerciseName : String = ""

    var parentWorkout = LinkingObjects(fromType: Workouts.self, property: "exercise")

    let wsr = List<WeightSetsReps>()
}

class WeightSetsReps : Object {
    @objc dynamic var weight = 0
    @objc dynamic var reps = 0
    var parentExercise = LinkingObjects(fromType: Exercises.self, property: "wsr")
}





 override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {

            if editingStyle == .delete {
                try! realm.write {

                    if days?[indexPath.section].workout[indexPath.row].exercise[indexPath.row] != nil {
                        realm.delete(((days?[indexPath.section].workout[indexPath.row].exercise[indexPath.row].wsr)!))
                        realm.delete(((days?[indexPath.section].workout[indexPath.row].exercise)!))
                        realm.delete((days?[indexPath.section].workout[indexPath.row])!)
                    } else {
                        realm.delete((days?[indexPath.section].workout[indexPath.row])!)
                    }


                    tableView.beginUpdates()

                    tableView.deleteRows(at: [indexPath], with: .automatic)

                    if days?[indexPath.section].workout.isEmpty == true {
                        realm.delete((days?[indexPath.section])!)
                        let indexSet = IndexSet(arrayLiteral: indexPath.section)
                        tableView.deleteSections(indexSet, with: .automatic)
                    }

                    tableView.endUpdates()
                }
            }
        }

I'm trying to delete the parent object along with all of its related child objects upon execution of swipeToDelete.

The way it's set up right now, when there are multiple child objects in the parent object, and I swipe to delete that parent object, only one of the child objects get deleted.

How can I delete all of the child objects?

Upvotes: 3

Views: 949

Answers (1)

Jay
Jay

Reputation: 35648

This question has numerous answers; from reading in the workouts from the Days' List object and iterating over them to delete each one - to - querying for the days matching workouts and then delete

Let's do a query. Realm objects are lazily loaded so if there's 10 or 10,000, the memory impact will be minimal and will avoid an iteration loop would could slow the UI.

The first thing to note is there's an inverse relationship between Days and their parent Workout objects.

We can leverage that relationship to select which workouts belong to which days and then delete them.

The second thing is that realm.delete can be passed a single object to delete or a sequence of objects.

Here's the code. I don't know which day and workouts objects you want to delete, so I am going to delete the workouts that go with the first day object.

if let day = realm.objects(Days.self).first {
    let thisDaysWorkouts = realm.objects(Workouts.self).filter("ANY parentDay == %@", day)
    try! realm.write {
        realm.delete(thisDaysWorkouts)
    }
}

Once those are deleted, you can delete the parent object.

Note that Realm doesn't currently have cascading delete's.

As an unrelated side note, you may want to consider giving your objects Primary Keys. It will help with organization in the long run as the project grows.

Upvotes: 2

Related Questions