I made simple school & student model with RelationShip
import SwiftUI
import SwiftData
@Model final class School {
var name: String
@Relationship(deleteRule: .cascade, inverse: \Student.school)
var studentList: [Student] = [Student]()
init(name: String) {
self.name = name
}
}
@Model final class Student {
var name: String
var school: School?
init(name: String) {
self.name = name
}
}
~
struct SchoolView: View {
@Environment(\.modelContext) private var modelContext
@Query(sort: \School.name) var schools: [School]
@Query(sort: \Student.name) var students: [Student]
var body: some View {
NavigationStack {
List {
ForEach(schools) { school in
NavigationLink {
StudentView(school: school)
} label: {
HStack {
Text(school.name)
Spacer()
Text("\(school.studentList.count)")
}
}
.swipeActions {
Button(role: .destructive) {
deleteSchool(school)
} label: {
Label("Delete", systemImage: "trash")
}
}
}
.onDelete(perform: deleteSchools(at:))
}
.navigationTitle("Home")
.listStyle(.plain)
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button {
addSchool()
} label: {
Image(systemName: "plus")
}
}
ToolbarItem(placement: .topBarLeading) {
VStack(alignment: .leading) {
Text("School: \(schools.count)")
Text("Student: \(students.count)")
}
}
}
}
}
private func randomString() -> String {
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
return String((0..<5).map { _ in letters.randomElement()! })
}
private func addSchool() {
let newSchool = School(name: randomString())
modelContext.insert(newSchool)
}
private func deleteSchools(at offsets: IndexSet) {
offsets.map { schools[$0] }.forEach(deleteSchool)
}
private func deleteSchool(_ school: School) {
modelContext.delete(school)
try? modelContext.save()
}
}
struct StudentView: View {
@Environment(\.modelContext) private var modelContext
var school: School
var body: some View {
List {
ForEach(school.studentList) { student in
Text(student.name)
}
.onDelete(perform: deleteStudents(at:))
}
.navigationTitle("Home")
.navigationBarTitleDisplayMode(.inline)
.listStyle(.plain)
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button {
addStudent()
} label: {
Image(systemName: "plus")
}
}
}
}
private func addStudent() {
let newSchool = Student(name: randomString())
modelContext.insert(newSchool)
newSchool.school = school
school.studentList.append(newSchool)
}
private func randomString() -> String {
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
return String((0..<5).map { _ in letters.randomElement()! })
}
private func deleteStudents(at offsets: IndexSet) {
withAnimation {
offsets.forEach {
let student = school.studentList[$0]
modelContext.delete(student)
try? modelContext.save()
}
}
}
}
I try my best to follow the SampleTrips app from Apple developer.
When I delete one of the schools, then all the students in the school should be deleted. But the student count never changes. Deleting the student itself works well - the student count decreases.
Thank you!