Realm.io API mapping parent object automatically

1k views Asked by At

I am using Realm and its REST API's mapping method to map JSON data to my models and their child relationships automatically. It works great, except when I add in a "To-One" relationship on the child models referencing the parent. The mapping goes all out of whack and creates additional entries that don't exist.

The parent model:

class Foo: Object {
  dynamic var id = 0
  dynamic var title = ""
  let bars = List<Bar>() // Children

  override class func primaryKey() -> String {
    return "id"
  }
}

The child model:

class Bar: Object {
  dynamic var id = 0
  dynamic var title = ""
  dynamic var foo = Foo() // Reference to parent

  override class func primaryKey() -> String {
      return "id        
  }
}

Per the documentation I am mapping the JSON using the convenience method:

let foos = JSON["foos"] as! [NSDictionary]
  let realm = Realm()
  realm.write {
    for foo in foos {
      realm.create(Foo.self, value: foo, update: true)
    }
  }

I'm aware I could set up the mapping manually, but I want to make use of the convenience method if possible at all. Does anyone know how to set this up?

2

There are 2 answers

1
Ismail On BEST ANSWER

I think you better use Inverse Relationships for ToOne relationship instead. Foo class will be the same. but you will change foo property in Bar class, like the following.

    class Bar: Object {
        dynamic var id = 0
        dynamic var title = ""
       //dynamic var foo = Foo() // Reference to parent
        dynamic var foo: FOO {
        // Realm doesn't persist this property because it only has a getter defined
        // Define "foo" as the inverse relationship to Foo.bars
        return linkingObjects(Bar.self, forProperty: "bars").first as! Foo
       }

      override class func primaryKey() -> String {
          return "id        
      }
   }
1
jpsim On

Ismail's answer is correct and I've upvoted it: Realm's query engine only works with properties persisted in the database. If you want to add a persisted backlink property, you'll have to set it yourself.

For example:

let foos = JSON["foos"] as! [NSDictionary]
let realm = Realm()
realm.write {
  for foo in foos {
    let persistedFoo = realm.create(Foo.self, value: foo, update: true)
    for bar in persistedFoo.bars {
      bar.foo = foo
    }
  }
}