SwiftData: how to reference same model?

I have the following model:

@Model
class Person {
   var name = ""
   @Relationship(deleteRule: .nullify, inverse: \Person.ref) var ref: Person? = nil
}

Now consider the following code:

let peter: Person
let cristina: Person
peter.ref = cristina
modelContext.delete(cristina)

I would expected that peter.ref is nil, because referenced person was deleted. In reality, this won't even compile due to this error: Circular reference resolving attached macro 'Relationship'

If I remove 'inverse' from the relationship it will compile, but it does not do what I need then.

So is it possible to have a reference on the model itself with nullify capability?

PS Using Xcode 15 beta 7

The inverse of a SwiftData relationship cannot point back to itself. This is what the circular reference error is referring to. You need to add another property that can be used for the inverse relationship. You don't have to use this property, it's just to satisfy SwiftData's relationship requirements. For example:

@Model final class Person {
    var name = ""

    @Relationship(deleteRule: .nullify, inverse: \Person.inverseRef) var ref: Person? = nil

    // Call this whatever you want
    // Can make private if not using elsewhere
    @Relationship var inverseRef: Person?
}


Testing this and adding

dump(peter.ref)

after deleting cristina yields this output:

Optional(Person)
  ▿ some: Person #0
    - _name: Person._SwiftDataNoType
    ▿ _ref: Optional(Person._SwiftDataNoType())
      - some: Person._SwiftDataNoType
    - _inverseRef: nil
    ...

So peter.ref is not nil but it seems to be an "empty" model with "empty" values, essentially nullified. Whether this is the behaviour you want, I don't know, but I hope it fixes your inverse relationship problem.


BTW, nullify is the default delete rule for relationships so it doesn't need specifying.

SwiftData: how to reference same model?
 
 
Q