BObereder
BObereder

Reputation: 1046

Perform Realm migration from one List to another

In my model I want to migrate a List<Item> where that Item holds a custom class product like:

class Item: Object {

  dynamic var product: Product?

}

to simply a List<Product>

I tried different things but nothing really seems to work. For example something like this:

let items = oldObject.dynamicList("items")

for item in items {
  let oldProduct = item["product"] as! MigrationObject
  productList.append(oldProduct)
}

This leads to an error saying that this object already is persisted.

If I create a new Product in the migration block I will have duplicated objects in my realm.

I also tried assigning directly to the list like: newObject!["products"] without appending but also couldn't get it to work.

What is the real solution to that migration problem can someone point me in the right direction?

Upvotes: 3

Views: 2630

Answers (2)

marius
marius

Reputation: 7806

The problem here is that you're implicitly attempting to add objects which are already managed in another Realm to the list, which is in general not allowed. The other Realm here is the old previous version here.

You can solve that by doing the following when you enumerate over your model:

migration.enumerate("ObjectWithProductsList") { (oldObject, newObject) in
    let productList = newObject.dynamicList("products")
    let items = oldObject.dynamicList("items")
    let newRealm = newObject.realm

    for item in items {
        let oldProduct = item["product"] as! MigrationObject
        let newProduct = newRealm.objects(Product).where("id = %@", oldProduct["id"])
        productList.append(newProduct)
    }
}

Upvotes: 4

kishikawa katsumi
kishikawa katsumi

Reputation: 10573

Can you try the code like the following? The error "object already is persisted" is occurred due to storing oldObject, I think.

First, enumerate Item class to collect Product objects. Then get Product object from newObject. Then append the objects to the List<Product>.

let objectToHoldListOfItems = migration.create("...")

migration.enumerate("Item", { (oldObject, newObject) in
    if let _ = oldObject, let newObject = newObject {
        let product = newObject["product"] as! DynamicObject

        let products = objectToHoldListOfItems["products"] as! List<DynamicObject>
        products.append(product)
    }
})

Upvotes: 0

Related Questions