Realm - Can't create object with existing primary key value

后端 未结 2 2089
暖寄归人
暖寄归人 2021-01-01 16:39

I have a object Person with many dogs. App has separate page where it shows just dogs and other page where it shows person\'s dogs

My model is as follows

<
相关标签:
2条回答
  • 2021-01-01 17:19

    The problem here is that even though you're creating a completely new Realm Dog object, you're not actually persisting that one to the database, and so when you call append, you're trying to add a second copy.

    When you call realm.create(Dog.self, value:dog, update: true), if an object with that ID already exists in the database, you're simply updating that existing object in with the values in the dog instance you created, but that dog instance is still an independent copy; it's not the Dog object in the database. You can confirm this by checking if dog.realm is equal to nil or not.

    So when you call person.dogs.append(dog), because dog is not already in the database, Realm tries to create a whole new database entry, but fails because there is already a dog with that ID.

    If you want to append that dog object to a person, it'll be necessary to query Realm to retrieve a proper dog object that's referencing the entry in the database. Thankfully this is really easy with Realm objects backed by primary keys since you can use the Realm.object(ofType:forPrimaryKey:) method:

    if let person = realm.object(ofType: Person.self, forPrimaryKey: "id") {
        for (_, dict): (String, JSON) in response {
            //Create dog using the dict info,my custom init method
            if let dog = Dog(dict: dict)
            {
                try! realm.write {
                    //save it to realm
                    realm.create(Dog.self, value: dog, update: true)
                    //get the dog reference from the database
                    let realmDog = realm.object(ofType: Dog.self, forPrimaryKey: "id")
                    //append dog to person
                    person.dogs.append(realmDog)
                }
            }
        }
        try! realm.write {
            //save person
            realm.create(person .self, value: collection, update: true)
        }
    }
    
    0 讨论(0)
  • 2021-01-01 17:26

    We don't need TiM's method anymore.

    Use add(_:update:).

    try realm.write {
        realm.add(objects, update: Realm.UpdatePolicy.modified)
        // OR
        realm.add(object, update: .modified)
    }
    

    Realm.UpdatePolicy enums:

    error (default)
    modified //Overwrite only properties in the existing object which are different from the new values.
    all //Overwrite all properties in the existing object with the new values, even if they have not changed
    

    NB: Works on Realm Swift 3.16.1

    0 讨论(0)
提交回复
热议问题