I tried to use the .deny deleteRule but it seems to have no effect.
The toolbar button adds an item with a relationship to a category to the context. Swiping on the category deletes the category even though an item is referencing the category. There is also no error thrown when saving the context. It is as if the deleteRule was not there.
For other deleteRules like .cascade, the provided sample code works as expected.
import SwiftUI
import SwiftData
@Model
class Category {
var name: String
@Relationship(deleteRule: .deny) var items: [Item] = []
init(name: String) {
self.name = name
}
}
@Model
class Item {
var name: String
var category: Category?
init(name: String, category: Category) {
self.name = name
self.category = category
}
}
struct DenyDeleteRule: View {
@Environment(\.modelContext) private var modelContext
@Query private var categories: [Category]
@Query private var items: [Item]
var body: some View {
List {
Section("Items") {
ForEach(items) { item in
Text(item.name)
}
}
Section("Categories") {
ForEach(categories) { category in
VStack(alignment: .leading) {
Text(category.name).bold()
ForEach(category.items) { item in
Text("• \(item.name)")
}
}
}
.onDelete(perform: deleteCategory)
}
}
.toolbar {
Button("Add Sample") {
let category = Category(name: "Sample")
let item = Item(name: "Test Item", category: category)
modelContext.insert(item)
}
}
}
func deleteCategory(at offsets: IndexSet) {
for index in offsets {
let category = categories[index]
modelContext.delete(category)
do {
try modelContext.save()
} catch {
print(error)
}
}
}
}
#Preview {
NavigationStack {
DenyDeleteRule()
}
.modelContainer(for: [Item.self, Category.self], inMemory: true)
}