According to the Realm documentation for v0.102.0, this is how you create an inverse relationship:
class Person: Object {
// ... other property declarations
let dogs = List<Dog>()
}
class Dog: Object {
// ... other property declarations
let owners = LinkingObjects(fromType: Person.self, property: "dogs")
}
Suppose that we have another class, called DogFood
, and we want to create an inverse relationship called buyers
that tracks which instances of Person
have a Dog
that eats that instance of DogFood
. We could try the following:
class Dog: Object {
// ... other property declarations
let favoriteFoods = List<DogFood>
let owners = LinkingObjects(fromType: Person.self, property: "dogs")
}
class DogFood: Object {
// ... other property declarations
let buyers = LinkingObjects(fromType: Person.self, property: "dogs.favoriteFoods")
}
However, this throws the following error: Property 'dogs.favoriteFoods' declared as origin of linking objects property 'buyers' does not exist.
Is there another way to achieve the same effect?
This can be achieved with a filter, with the caveat that the DogFood
object we need to query about needs to be part of a Realm
.
The code would go as follows:
class DogFood: Object {
// ... other property declarations
var items: Results<Person> {
if let realm = self.realm {
return realm.objects(Person).filter(NSPredicate(format: "ANY dogs.favoriteFoods.id == %@", self.id))
} else {
return RealmSwift.List<Person>().filter("1 != 1")
}
}
}
The property realm
is of type Realm?
and comes into the picture through inheritance from Object
. It points towards the realm that a particular Object
instance is in and returns nil
if not assigned to one. If that is the case, we force the property items
to return an empty set of Results<Person>
.