Reputation: 1
I'm starting use Realm.io and I need to add or update a To-Many relationship RLMObject. Imagine I have RLMObjects like this:
#import <Realm/Realm.h>
@class Person;
// Dog model
@interface Dog : RLMObject
@property NSInteger id;
@property NSString *name;
@end
RLM_ARRAY_TYPE(Dog) // define RLMArray<Dog>
// Person model
@interface Person : RLMObject
@property NSString *name;
@property NSDate *birthdate;
@property RLMArray<Dog *><Dog> *dogs;
@end
RLM_ARRAY_TYPE(Person) // define RLMArray<Person>
Dogs RLMObject has a primary Key (id) and I'm reading a json with one person and various Dogs. How can I add the Person and their Dogs?
I'll loop json person and dogs array. If I use above code for example, realm warning about primary key violation on Dogs object:
RLMRealm *realm = [RLMRealm defaultRealm];
Dogs *dog = [[Dogs alloc] init];
[realm beginWriteTransaction];
dog.id = 1;
dog.name = @"Lupi";
[realm addOrUpdateObject:dog];
dog.id = 2;
dog.name = @"rex";
[realm addOrUpdateObject:dog];
[realm commitWriteTransaction];
Person *newPerson = [[Person alloc] init];
[realm beginWriteTransaction];
newPerson.id = 1;
newPerson.name = @"John";
[newPerson.dogs addObject:dog];
[realm addOrUpdateObject:newPerson];
[realm commitWriteTransaction];
Upvotes: 0
Views: 355
Reputation: 10573
If you get this error 'Primary key can't be changed after an object is inserted.'
, the reason is because you're trying to use the same object.
dog.id = 1;
dog.name = @"Lupi";
[realm addOrUpdateObject:dog];
dog.id = 2; // This is not allowed. The primary key of the object that was saved once can not be changed.
dog.name = @"rex";
[realm addOrUpdateObject:dog];
Realm object is not a just value object. When the Realm object is saved once, it will be changed to a special object that connected to the database.
So dog.id = 2;
means that you will change the object that you just saved.
You should create new instance every time when you'd like to save new objects. Like the following:
Dog *dog1 = [[Dog alloc] init];
dog1.id = 1;
dog1.name = @"Lupi";
[realm addOrUpdateObject:dog1];
Dog *dog2 = [[Dog alloc] init];
dog2.id = 2;
dog2.name = @"rex";
[realm addOrUpdateObject:dog2];
[realm commitWriteTransaction];
If you will create new objects from JSON like the following:
{
"person": {
"id": 1,
"name": "foo",
"birthdate": "1980/10/28",
"dogs": [
{
"id": 1,
"name": "bar"
},
{
"id": 2,
"name": "baz"
}
]
}
}
You can just loop the dogs array, create new Realm objects every loop.
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSDictionary *person = json[@"person"];
[realm beginWriteTransaction];
Person *newPerson = [[Person alloc] init];
newPerson.id = [person[@"id"] integerValue];
newPerson.name = person[@"name"];
NSArray *dogs = person[@"dogs"];
for (NSDictionary *dog in dogs) {
Dog *newDog = [[Dog alloc] init];
newDog.id = [dog[@"id"] integerValue];
newDog.name = dog[@"name"];
[realm addOrUpdateObject:newDog];
}
[realm addOrUpdateObject:newPerson];
[realm commitWriteTransaction];
Upvotes: 1