2016-11-14 5 views
3

У меня есть объект Человек со многими собаками. Приложение имеет отдельную страницу, где он показывает только собака и другую страницу, где он показывает собака от PERSONRealm - Невозможно создать объект с существующим значением первичного ключа

Моей модели выглядит следующим образом

class Person: Object { 
    dynamic var id = 0 
    let dogs= List<Dog>() 

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

class Dog: Object { 
    dynamic var id = 0 
    dynamic var name = "" 

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

У меня есть человек, хранящийся в Realm. У человека есть страница с деталями, где мы получаем и показываем его собак. Если собака уже существует, я обновляю последнюю информацию для этой собаки и добавляю ее в список собак человека, создавая новую собаку, сохраняя ее и добавляя в список людей. Это работает в coredata.

// Fetch and parse dogs 
if let person = realm.objects(Person.self).filter("id =\(personID)").first { 
    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, value:dog, update: true) 
       // append dog to person 
       person.dogs.append(dog) 
      } 
     } 
    } 
    try! realm.write { 
     // save person 
     realm.create(Person.self, value: person, update: true) 
    } 
} 

На попытке обновить человека с его собаками, сфера бросает исключение Невозможно создать объект с существующим значением первичного ключа

+1

Где 'recipe' значение в' person.dogs.append (рецепт) 'приходит? Не совсем понятно, что вы пытаетесь сделать здесь, извините! – TiM

+0

Извините, это должен быть person.dogs.append (собака). Я просто создаю/обновляю собаку и добавляю ее собакам человека @TiM –

+1

Ahh okay. Кажется, я вижу, что здесь происходит сейчас. Я добавлю ответ. :) – TiM

ответ

18

Проблема здесь состоит в том, что даже если вы создаете совершенно новый Realm Dog, вы фактически не сохраняете это в базе данных, поэтому, когда вы вызываете append, вы пытаетесь добавить вторую копию.

При вызове realm.create(Dog, value:dog, update: true), если объект с таким идентификатором уже существует в базе данных, вы просто обновление, что существующий объект со значениями в dog случае вы создали, но dog экземпляр остается независимым от копирования; это не объект Dog в базе данных. Вы можете подтвердить это, установив, что dog.realm равно nil или нет.

Поэтому, когда вы вызываете person.dogs.append(dog), потому что dog еще нет в базе данных, Realm пытается создать совершенно новую запись в базе данных, но терпит неудачу, потому что уже есть собака с этим ID.

Если вы хотите добавить, что dog объекта в person, это будет необходимо запросить Realm для получения надлежащего dog объекта, который ссылающиеся на запись в базе данных. К счастью, это очень легко с объектами Realm поддержанных первичными ключами, так как вы можете использовать Realm.object(ofType:forPrimaryKey:) метод:

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, 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

В моем случае у меня есть 6 событий для сохранения, каждый из которых имеет уникальный тип. Im сохраняет все эти 6 событий в таблице заданий. Но когда я пытаюсь создать еще один объект задания с другим идентификатором задания, когда я создаю первое задание fir для второго события. Я получаю ошибку. не может создать объект с одним и тем же первичным ключом. –

+0

Если вам нужно, вам может потребоваться запросить базу данных, чтобы узнать, существует ли объект с тем же самым первичным ключом. Эта ошибка возникает только при попытке добавить второй объект с тем же самым первичным ключом, поэтому вам просто нужно убедиться, что ваша логика этого не делает. :) – TiM