Reputation: 1795
I am trying to persist a list of ObjectB is ObjectA, where adding ObjectA to list fails and making the whole write transaction fail. The code as below,
public final class User: Object {
@Persisted(primaryKey: true) public var userObjectId: ObjectId
.......
@Persisted public var assignments: List<Assignment>
.......
}
public final class Assignment: Object {
@Persisted(primaryKey: true) public var assignmentObjectId: ObjectId
@Persisted public var name: String?
}
With the above models, I try to do the below to create an assignment and add the created assignment to the user's assignments list,
func createAssignentForUser(_ user: User) {
do {
let realm = Realm()
try realm.write {
let assignment = Assignment(name: "ass_name")
realm.add(assignment)
user.assignments.append(assignment) //something feels wrong here.
}
} catch {
// handle error
}
}
If I put a debug pointer and query user.assignments.count, I can see the count as 1 when the corresponding line is executed. But when I open the Database to see the inserted objects,I neither see any entry created for Assignment entity, nor any assignment added to user's assignments list. Both are zero. The above code doesn't throw any error either.
Now, if I remove the line user.assignments.append(assignment)
from the above code, then it does create an entry in the Assignment entity.
With this line present, it doesn't seem to create the assignment itself, i.e, the line realm.add(assignment)
itself doesn't seem to work.
So what is wrong with the above code? Isn't above the correct way of adding created object to a list ?
Upvotes: 1
Views: 180
Reputation: 35648
There are a number of things to correct but in general, the code will be ok with a minor tweak or two and a bit of backing information:
First, avoid Realm and Swift collisions; a List
is also a SwiftUI object and that can cause compiler confusion. Change the List
in this
@Persisted public var assignments: List<Assignment>
to this
@Persisted public var assignments: RealmSwift.List<Assignment> //added RealmSwift
Second, the public var can just be var.
public var userObjectId: ObjectId
Next, this should not work or even compile (it throws a compiler error for me Incorrect argument label in call (have 'name:', expected 'value:')
let assignment = Assignment(name: "ass_name")
...as that's how to compose a Struct. In Realm we use classes and you'll need a convenience init in your Realm object
public final class Assignment: Object {
@Persisted(primaryKey: true) public var assignmentObjectId: ObjectId
@Persisted public var name: String?
convenience init(name: String) {
self.init()
self.name = name
}
}
Lastly, where you noted this
//something feels wrong here
There's actually nothing wrong - but it is redundant.
realm.add(assignment)
persists the assignment object; but Realm is pretty smart - if an object does not exist but needs to, it will also persist the assignment
object here
user.assignments.append(assignment)
And will also add the assignment
object to the assignments List.
Upvotes: 0