Using RealmSwift to save an one-to-many relationsh

2019-08-30 05:51发布

I'm coming from a Ruby on Rails-like data structure in terms of relationships.

So in Rails: Foo has many Bars and Bar has one Foo.

Going through the RealmSwift docs, I came up with this, I think:

class Foo: Object {
  // other props
  var bars = List<Bar>() // I hope this is correct
}

class Bar: Object {
  // other props
  @objc dynamic var foo: Foo?
}

If the above is corrct, I struggle to know how to create this relationship object.

// I need to create Foo before any Bar/s
var foo = Foo()
foo.someProp = "Mike"

var bars = [Bar]()
var bar = Bar()
bar.someProp1 = "some value 1"
bars.insert(bar, at: <a-dynamic-int>)

This is where I am at a full stop:

// Create Foo
try! realm.write {
  realm.add(foo)
  // But.... I need to append bars, how?
}

try! realm.write {
   for bar in bars {
      // realm.add(bar)
      // I need to: foo.append(bar) but how and where?
   }
}

In the end, I should be able to foo.bars to see an array of bars and bar.foo to get foo

foo and bar have not yet been created so do not know how to chain the lot to save at once. Possible? How? If you are providing an answer, can you post a reference to the doc for future reference? That would count as an answer for me. Thanks

1条回答
Juvenile、少年°
2楼-- · 2019-08-30 06:18

This should get you started:

class Foo: Object {
    // other props
    @objc dynamic var id = ""
    let bars = List<Bar>()

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

class Bar: Object {
    // other props
    @objc dynamic var id = ""
    let foo = LinkingObjects(fromType: Foo.self, property: "bars")

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

let foo = Foo()
foo.id = "somethingUnique"
foo.someProp = "Mike"

let bar = Bar()
bar.id = "somethingUnique"
bar.someProp1 = "some value 1"

try! realm.write {
    realm.add(foo)
    realm.add(bar)
    foo.bars.append(bar)
}

let anotherBar = Bar()
anotherBar.id = "somethingUnique"
anotherBar.someProp1 = "some other value"
try! realm.write {
    realm.add(anotherBar)
    foo.bars.append(anotherBar)
}

Elsewhere:

var currentBars: List<Bar>()
if let findFoo = realm.object(ofType: Foo.self, forPrimaryKey: "someUniqueKey") {
    currentBars = findFoo.bars
    // to filter
    if let specificBar = currentBars.filter("id = %@", id) {
        // do something with specificBar
    }
}

To get foo from bar:

if let bar = realm.object(ofType: Bar.self, forPrimaryKey: "theUniqueID") {
    if let foo = bar.foo.first {
        // you have your foo
    }
}

If I'm understanding your comment correctly:

// already created foo
for nonRealmBar in nonRealmBars {
    // Note: you could also use realm.create
    let bar = Bar()
    bar.id = nonRealmBar.id
    bar.someProp = nonRealmBar.someProp
    // fill in other properties;
    try! realm.write {
        realm.add(bar)
        foo.bars.append(bar)
    }
}
查看更多
登录 后发表回答