hitrain
hitrain

Reputation: 173

realm swift . How to link to exist object with primary key

i have mapping class (simplified models)

class Album: Object, Mappable {

    dynamic var id = 0
    var images : List<AlbumImage>?

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

    required convenience init?(map: Map) {
        self.init()
    }

    func mapping(map: Map) {
        id <- map["id"]
        images <- (map["images"], ListTransform<AlbumImage>())
    }
}

class AlbumImage: Object, Mappable {
    dynamic var src = ""

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

    required convenience init?(map: Map) {
        self.init()
    }

    func mapping(map: Map) {
        src <- map["src"]
    }
}

class AnotherAlbum: Object {

    dynamic var id = 0
    var images = List<AlbumImage>()

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

mapping is perfect, but need create another object with exists AlbumImage

let aa = AnotherAlbum()
aa.id = album.id
aa.images.append(objectsIn: album.images!)

or

let aa = AnotherAlbum()
aa.id = album.id
aa.images = album.images!

then i delete this created object realm.delete(aa), restart app and create again from code upper

get error

Terminating app due to uncaught exception 'RLMException', reason: 'Can't create object with existing primary key value 'https://example.com/1.jpg'.'

How right link exist object from another model but not create them?

Upvotes: 1

Views: 1615

Answers (1)

TiM
TiM

Reputation: 15991

The simple fact is Realm disallows two separate Objects with matching primary keys. You cannot instantiate a wholly new object (ie with let newImage = AlbumImage()) and then add it to the database, as Realm will try to treat this as a completely separate image.

If you create a new unmanaged Object, then when you try and append it to a List, in the same transaction, it will try and add that object to Realm as well. It's at this point that if the new object has a matching primary key to an existing object that the exception will occur.

To avoid this, you can do potentially 2 things:

  • You can query for pre-existing objects with the same primary key by doing `let image = try! Realm().object(ofType: AlbumImage.self, forPrimaryKey: "https://example.com/1.jpg"). You can then update this object, instead of creating a new one from scratch.
  • You can change your logic to use realm.add(albumImage, update: true). This will merge your new object with the same primary key with the one already in your database.

Good luck!

Upvotes: 1

Related Questions