Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add existing objects on a new class on Realm Migration in Android

I have an app on production, so changes has to be applied with a RealmMigration

I've looked the documentation and this example but I didn't find how to do the following.

In current version I have items of type Foo that has a boolean property called favorite. Now I want to generalize that and create user custom Foo lists, so the users will be able to create their custom lists and add as many objects as they want. I want to implement this with a new class called UserFooList with basically name and a RealmList<Foo>of elements.

In migration process I'm creating this new class with its fields.

That's easy, but here comes the difficult part:

I want to add all previous Foo items flagged with favorite to a new UserFooList and then remove the now unused Foo's field favorite


Some code to help to clarify:

Current class

public class Foo extends RealmObject{

    private String title;
    private boolean favorite;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public boolean isFavorite() {
        return favorite;
    }

    public void setFavorite(boolean favorite) {
        this.favorite = favorite;
    }
}

Changed class

public class Foo extends RealmObject{

    //favorite field will be removed
    private String title;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}

New class

public class UserFooList extends RealmObject{

    private String name;
    private RealmList<Foo> items;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public RealmList<Foo> getItems() {
        return items;
    }

    public void setItems(RealmList<Foo> items) {
        this.items = items;
    }
}

I want to insert a UserFooList instance and populate it with:

  • name: "favorites"
  • items: all existing Foo instances with favorite == true

And I want to do it during Migration because in that way I will be able to remove favorite field after inserting all elements in the new created list.

like image 614
pauminku Avatar asked May 31 '18 14:05

pauminku


1 Answers

Rely on the power of the DynamicRealm API.

public class MyMigration implements Realm.Migration {    
    @Override
    public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {
        RealmSchema schema = realm.getSchema();
        if(oldVersion == 0) {
            RealmObjectSchema foo = schema.get("Foo");
            RealmObjectSchema userFooList = schema.create("UserFooList");
            userFooList.addField("name", String.class);
            userFooList.addRealmListField("items", foo);

            DynamicRealmObject userList = realm.createObject("UserFooList");
            userList.setString("name", "favorites");
            RealmList<DynamicRealmObject> listItems = userList.getList("items");
            RealmResults<DynamicRealmObject> favoriteFoos = realm.where("Foo").equalTo("favorite", true).findAll();
            for(DynamicRealmObject fooObj: favoriteFoos) {
                listItems.add(fooObj);
            }
            foo.removeField("favorite");
            oldVersion++;
        }
    }

    @Override public boolean equals(Object object) { 
        return object != null && object instanceof MyMigration;
    }

    @Override public int hashCode() {
        return MyMigration.class.hashCode();
    }
}
like image 63
EpicPandaForce Avatar answered Nov 16 '22 06:11

EpicPandaForce