Reputation: 105
I have a SwiftData model called Workout that contains a array of Exercise Model which itself contains an array of Sets Model,
Before I had a copy method in these models for creating a new object from the properties of old objects and it worked correctly, but since introducing Relationships between these models whenever I try to call the copy method of Exercise I get the error message:
Fatal error: Unsupported relationship key path ReferenceWritableKeyPath<MySet, Exercise>
This are the copy methods:
@Model
class Workout: Identifiable {
var id: UUID
var name: String
@Relationship(deleteRule: .cascade, inverse: \Exercise.workout) //when deleting a workout you delete all exericses that happened during that workout
var exercises: [Exercise]?
var startTime: Date
var endTime: Date
func copy() -> Workout {
let workout = Workout(id: UUID(), name: name, startTime: startTime, endTime: endTime)
workout.name = name
workout.startTime = Date.now
workout.endTime = Date.now
workout.exercises = exercises?.map { $0.copy() }
return workout
}
init(id: UUID, name: String = "", startTime: Date = Date.now, endTime: Date = Date.now) {
self.id = id
self.name = name
self.startTime = startTime
self.endTime = endTime
}
}
@Model
class Exercise: Identifiable {
var id: UUID
var exerciseName: ExerciseName
@Relationship(deleteRule: .cascade, inverse: \MySet.exercise)
var sets: [MySet]? //When an Exercise gets Deleted all Sets associated need to get deleted
var date: Date
var workout: Workout
func copy() -> Exercise {
let newExercise = Exercise(id: UUID(), exerciseName: exerciseName, date: Date.now, workout: workout)
// Copy the related sets
if let existingSets = sets {
newExercise.sets = existingSets.map { set in
// Copy each set and associate it with the newExercise
let newSet = set.copy(exercise: newExercise)
return newSet
}
}
return newExercise
}
init(id: UUID, exerciseName: ExerciseName, date: Date, workout: Workout) {
self.id = id
self.exerciseName = exerciseName
self.date = date
self.workout = workout
}
}
@Model
class MySet: Identifiable {
var id: UUID
var weight: Int
var reps: Int
var isCompleted: Bool
var exercise: Exercise
var date: Date
//make a copy functionality so you can call this and pass it an Exercise when copying a Set
func copy(exercise: Exercise) -> MySet {
MySet(id: UUID(), weight: weight, reps: reps, isCompleted: isCompleted,date: Date.now , exercise: exercise)
}
init(
id: UUID,
weight: Int,
reps: Int,
isCompleted: Bool,
date: Date,
exercise: Exercise
) {
self.id = id
self.weight = weight
self.reps = reps
self.isCompleted = isCompleted
self.date = date
self.exercise = exercise
}
}
Xcode says the error occurs in the set method of var sets: [MySet]?
why did these copy methods work before introducing an inverse relationships between these models and not now?
Upvotes: 0
Views: 113
Reputation: 84
According to this answer here, you cannot set a relationship without using modelContext. So we need two things to do
Here is the code example (I hope it works):
func copy() -> Exercise {
let newExercise = Exercise(id: UUID(), exerciseName: exerciseName, date: Date(), workout: workout)
context.insert(newExercise)
// Copy each set and associate it with the new exercise
if let _sets = sets {
newExercise.sets = _sets.map { set in
let newSet = MySet(id: UUID(), weight: set.weight, reps: set.reps, isCompleted: set.isCompleted, date: Date.now, exercise: newExercise)
// Insert the newSet into the model context
context.insert(newSet)
return newSet
}
}
return newExercise
}
Upvotes: 0