Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document differences between List vs LinkingObjects and when to use which #4193

Open
cmelchior opened this issue Oct 7, 2016 · 5 comments
Open
Labels

Comments

@cmelchior
Copy link
Contributor

cmelchior commented Oct 7, 2016

Copy from: realm/realm-java#3584


Oops, just realised I put this in realm-java, and although it applies to all, I am using Swift...

Realm provides two options for 1-to-many relationships - one where the parent has a reference to children (List) and one where the child has a reference to the parent (eg. myParent: Parent?). In the latter case, LinkingObjects can be used in the parent to easily get a reference to the children. It would be helpful if the documentation included some guidance on when to use each solution, or at least some pros and cons. (The documentation does warn about the pitfalls of using both together, which is good).

I have been using the second option because it seems more "proper", as it enforces each child to have only one parent (not trying to solve many-to-many here). However, most of the examples I've seen use List. My preference fell into a screaming heap when I wanted to serialize to JSON, for two reasons. Firstly, the LinkingObjects variable is unknown to the Realm schema, so I had to resort to using Mirror, which is unpleasant, but not a show-stopper. However, the second is that I could find no way to enumerate LinkingObjects generically. List has ListBase that provides access to the unerlying items, whereas LinkingObjectsBase does not. Or am I missing something? Nevertheless, it looks like the only situation where Realm provides two ways to achieve the same outcome, so further discussion in the documentation would be helpful. Excellent product by the way - Core Data always caused me grief.

@jpsim
Copy link
Contributor

jpsim commented Oct 10, 2016

We cover this in our documentation for Inverse Relationships. That section explains when you'd want to use Lists (explicit links) versus LinkingObjects (traversing Lists in the opposite direction).

@michaelblight is there something you think we should clarify further in that section?

@jpsim jpsim self-assigned this Oct 10, 2016
@michaelblight
Copy link

The documentation covers the options, but has no guidance as to when to use Links vs parent references. In both cases, you're probably going to use LinkingObjects to get the inverse relationship.

It would be helpful if the documentaiton said something like - Use List: when you want to support deep cloning (needs a schema reference from parent to child); when you want many-to-many relationships without needing an intermediary joining object (ala relational databases); when you want to maintain insertion order; when different Object types can reference same child type. Use parent references in the child: when you want to enforce a single parent in the database; (are there no other reasons despite it being the 'normal' relational db way to go??). I assume the performance differences between the two are immaterial (or that should be called out).

In the above, I don't make a very convincing argument for ever using parent references in the child, since List can do it anyway.

@hashemi
Copy link

hashemi commented Oct 16, 2016

I arrived here through Google having run into the same issue. I agree more guidance on pros and cons of each approach would be very useful. I don't know if this is correct but this is my impression:

Assume you have a list of car manufacturers with a nested list of cars in JSON:

[
  {
    "name": "BMW",
    "cars": [
      {
        "name": "5-series"
      },
      {
        "name": "7-series"
      },
    ]
  }
]

There are two ways to design this in Realm...

Approach 1. Reference nested items

class Manufacturer: Object {
    dynamic var name = ""
    let cars = LinkingObjects(fromType: Car.self, property: "manufacturer")
}

class Car: Object {
    dynamic var name = ""
    dynamic var manufacturer: Manufacturer?
}

At first glance, this approach looked more "correct" to me probably because of my experience with relational databases. However I quickly realized that this creates a mismatch between the database schema and the JSON schema which makes it hard to import straight and needed to create and link items manually.

Approach 2. Embed nested items

class Manufacturer: Object {
    dynamic var name = ""
    let cars = List<Item>()
}

class Car: Object {
    dynamic var name = ""
    let manufacturers = LinkingObjects(fromType: Manufacturer.self, property: "cars")
    var manufacturer: Manufacturer? {
        return self.manufacturers.first
    }
}

This approach makes it easy to import JSON including nested objects and Realm will do the right thing. The disadvantage is that linking back from Car to Manufacturer looks ugly because you can't link to a single parent object, it has to be a list, but a computed property can easily hide the issue at the call site.

I don't know what the performance characteristics of each approach are. I can only speculate that going through LinkingObjects is less performant making the second approach better in an app where a user selects a Manufacturer and gets a list of cars and the first approach may be better if you have a list of cars from different manufacturers and cars will be listed and accessed mainly through a many-to-many relationship of some sort (eg, list of user favourited cars).

@jpsim jpsim changed the title Guidance in documentation on List vs LinkingObjects Document differences between List vs LinkingObjects and when to use which Nov 9, 2016
@hartbit
Copy link

hartbit commented Nov 16, 2016

+1 I'd like some guidance here too

@aehlke
Copy link

aehlke commented Jul 26, 2024

I'd like guidance on performance of the two

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants