Search code examples
swiftswiftdata

How to detect if there is an object in the DB with the same filed value


I have the following model

@Model
final class Location {
    @Attribute(.unique) var name: String
    
    init(name: String) {
        self.name = name;
    }
}

And I have an EditView for this item. I don't want to let people try to save an item with already existing name.

        Button("Save") {
            withAnimation {
                save()
                dismiss()
            }
        }
        // Require a name to save changes.
        .disabled(
            name == "" || !isUnique())

...

private func isUnique() -> Bool {
    ForEach(locations) { location in
        if location.name == name {
            return true;
        }
    }
    return false;
}

I'm getting some design-time errors in isUnique function. How to do this properly?


Solution

  • You should perform a separate fetch if you can't make an in memory check

    func locationExists(for name: String, in modelContext: ModelContext) throws -> Bool {
        let predicate = #Predicate<Location> { $0.name == name }
        let fetchDescriptor = FetchDescriptor<Location>(predicate: predicate)
    
        return try modelContext.fetchCount(fetchDescriptor) > 0
    }
    

    I don't know why your function doesn't work but I would write it as

    private func isUnique(for name: String) -> Bool {
        locations.contains(where { $0.name == name }) == false
    }