3

Given the following data model, is there a way to update or set a child relationship without updating the (existing) child object?

Data Model

class Person: Object {
    dynamic var id = 0
    dynamic var dog: 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"
    }
}

Code

let realm = Realm()

// query existing dog
let existingDog = realm.objectForPrimaryKey(Dog.self, key: 42)
print(existingDog) // id: 42, name: Rex

// create new dog and person
let newDog = Dog(value: ["id": 42, "name": "Pluto"])
let person = Person()


realm.write {
    // this shouldn't update the existing dog
    // i.e. the name of the dog with id: 42 in the database should still be "Rex"
    person.dog = newDog
    realm.add(person, update: true)
}

I've also tried to do this via realm.create but had no success either. Any ideas?

schickling
  • 4,000
  • 4
  • 29
  • 33

1 Answers1

4

The id property in your Dog class is a primaryKey. Primary keys have the purpose to mark an entry in a Database as unique. So if you create an Object using the same primary key, you will override any existing data in the Database, which has the primary key.

I don't understand, what you exactly want to achieve, but there should be no reason for your Dog Table to have multiple Objects with the same primary key. That's not how Relational Databases are meant to work.

If you need however to have a Dog named Pluto and a Dog named Rex with the same id value, then should probably create a new attribute which is not unique (-> not marked as primary key).

ezcoding
  • 2,974
  • 3
  • 23
  • 32
  • Thanks for your answer. Maybe I was not that clear: I want to create a relation between the Person and the Dog with id 42 which already exists in the database. In SQL-speak I'd like to set `person.dog_id = 42`. – schickling Aug 02 '15 at 14:25
  • You did set up a relationship between a dog and a person. That doesn't protect you however from overriding an object in the dog Table having the same id. Under the hood realm probably creates a Table for you with the Columns: personId and dogId. There it defines the 1:1 relationship for you. That doesn't affect your dog Table in anyway though – ezcoding Aug 02 '15 at 14:28
  • ezcoding is correct the main purpose of the primary key is to make each object unique, another issue is that you currently have a 1:1 relationship. It seems that you want a person to be linked to multiple dogs so you should be using a one-to-many relationship with let dogs = List(). What is the end result you are trying to get? Do you want to remove the previous dog and then add the new one, but not delete the Dog from the database? – yoshyosh Aug 03 '15 at 16:36