Create Relationships in Atlas Device Sync for SwiftUI

Error : ***** Terminating app due to uncaught exception 'RLMException', reason: 'Cannot modify managed RLMArray outside of a write transaction.'**

I followed this documentation, which works. I ran into an error when I tried adding two relationships. See code below:

class Dog: Object, ObjectKeyIdentifiable {
    @Persisted(primaryKey: true) var _id: ObjectId
    @Persisted var name = ""
    @Persisted var owner: Person? // I beleive this is causing the error
    
    convenience init(name: String = "", owner: Person) {
            self.init()
            self.owner = owner
    }
}

class Person: Object, ObjectKeyIdentifiable {
    @Persisted(primaryKey: true) var _id: ObjectId
    @Persisted var name = ""
    @Persisted var dogs: List<Dog>
    
    convenience init(name: String) {
        self.init()
        self.name = name
    }
}

struct AddDogToPersonView: View {
    
    @ObservedRealmObject var person: Person
    @Environment(\.dismiss) var dismiss
    
    var body: some View {
        Form {
            Section {
                Button(action: {
                    $person.dogs.append(Dog(name: "Benny", owner: person))
                    dismiss.callAsFunction()
                }) {
                    Text("Save")
                }
                Button(action: {
                    dismiss.callAsFunction()
                }) {
                    Text("Cancel")
                }
            }
        }
    }
}

Could someone please explain what’s going on? The error says I can’t manage outside of a write transaction but it’s visible inside. Perhaps it has something to do with the fact that the dog has a reference to its owner. Here:

$person.dogs.append(Dog(name: "Benny", owner: person))

Hey Alexandar - in this case, I think you want the @Persisted var owner: Person? property in your Dog object to be an inverse link or back link to the Person object, which uses a different notation.

From the docs on Define an Inverse Relationship Property, the syntax you’re looking for is something like this:

@Persisted(originProperty: "dogs") var assignee: LinkingObjects<Person>

This creates a link back to the Person object, whose dogs list property you want to append the Dog object to.

(Also, if you’re using the SwiftUI property wrappers following the examples in the docs, you don’t need the convenience initializers.)

1 Like

But now the db of Dog shows a document with ownerId : ObjectId('000000000000000000000000')

After cleaning up my schema this worked. Thank you :clap: It’s odd that it the inverse relationship doesn’t show in the DB but I guess it makes sense.

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.