Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Single inverse relationship in Realm models

I'm developing a simple iOS app to learn Swift and I'm using Realm. As far as I know, in Realm inverse relationships are achieved with a LinkingObjects property which is a collection containing all objects linked to that one.

Consider this example from the Realm Documentation:

class Person: Object {
    // ... other property declarations
    let dogs = List<Dog>()
}

class Dog: Object {
    dynamic var name = ""
    dynamic var age = 0
    let owners = LinkingObjects(fromType: Person.self, property: "dogs")
}

In my model, I know that each Dog instance will only have one owner since every dog, when created is added to only one Person's List.

Now I'd like to have a owner: Person property in the Dog class that references to its only owner to make the code more intuitive and simpler (instead of having to write dog.owners.first every time) while keeping the lazy-loading behavior (they are lazily loaded, right?). I don't know how expensive it is to query the "Linking Objects", but since there will be many "Dogs" around, I think it would be better not to access them on object initialization.

For now these are the solutions I could think of:

1:

class Dog: Object {
    let owner: Person = LinkingObjects(fromType: Person.self, property: "dogs").first!
}

2a:

class Dog: Object {
    private let owners = LinkingObjects(fromType: Person.self, property: "dogs")
    lazy var owner: Person = {return self.owners.first!}()
}

2b:

class Dog: Object {
    lazy var owner: Person = {
        return LinkingObjects(fromType: Person.self, property: "dogs").first!
    }()
}

3:

class Dog: Object {

    private let owners = LinkingObjects(fromType: Person.self, property: "dogs")
    var owner: Person {
        return self.owners.first!
    }

}

I don't think "solution 1" is lazy loaded and, as in "solution 2", the owner won't be "auto-updating", however this shouldn't be a problem since in my case a Dog won't ever change owner.

What would you recommend to have a single inverse relationship in Swift?

like image 803
Lorenzo Rossi Avatar asked Jun 10 '16 18:06

Lorenzo Rossi


People also ask

Is realm a relational database?

What Is Realm? The Realm database is an open-source, easy-to-use alternative to Core Data and SQLite. It's a non-relational, NoSQL database that allows you to set up relationships between different objects.

What is realm react native?

Realm is a mobile database that runs directly inside phones, tablets or wearables. This project hosts the JavaScript versions of Realm. Currently we support React Native (both iOS & Android), Node. js and Electron (on Windows, MacOS and Linux).

Which objects are used in MongoDB?

An embedded object is a special type of Realm object that models complex data. They also map more naturally to the MongoDB document model. Embedded objects are similar to relationships, but provide additional constraints.


1 Answers

The only way is 3. Neither 1 nor 2a, 2b don't work.

Because at present LinkingObjectscan only be used to initialize a property of type LinkingObjects. Realm reads class definitions and all properties when initializing to define data schema. In the code of 1, owner property is treated as just Person property.

2a and 2b also don't work. Because Realm doesn't support lazy properties. Also 2b uses LinkingObjects in the wrong way same as 1.

So, only 3 works as expected.

See also... https://github.com/realm/realm-cocoa/issues/3525#issuecomment-216920757

like image 117
kishikawa katsumi Avatar answered Sep 18 '22 12:09

kishikawa katsumi