Data-swift / ManagedModels

A SwiftData like `@Model` infrastructure for CoreData.
https://www.alwaysrightinstitute.com/managedmodels/
Apache License 2.0
105 stars 5 forks source link

Circular reference resolving attached macro #18

Closed radianttap closed 1 year ago

radianttap commented 1 year ago

I have a model with entities Album and Artist and many-to-many relationship between them. Setting up inverse relationship yielded this error, not sure why it happens.

Screenshot 2023-10-01 at 13 12 38

Possibly related: I expanded the macro to see if I can figure something out and noticed this extra space in front of .self, seems like a typo..?

Screenshot 2023-10-01 at 13 13 25
radianttap commented 1 year ago

Relevant part of the model classes:

@Model class Artist: NSManagedObject, Decodable {
    @Relationship(inverse: \Album.artists)
    var albums: Set<Album>
}

@Model class Album: NSManagedObject, Decodable {
    @Relationship(inverse: \Artist.albums)
    var artists: Set<Artist>
}
helje5 commented 1 year ago

Hm, will check. The extra space doesn't matter.

radianttap commented 1 year ago

Looking at SwiftData example app from WWDC 2023 (Backyard Birds), it seems only one side of the relationship should be set in code, the other side is (likely) set automatically. This is contrary to what Core Data modeller explicitly asks you to do. 🤔

Thus this does not throw compiler errors:

@Model class Artist: NSManagedObject, Decodable {
    var albums: Set<Album>
}

@Model class Album: NSManagedObject, Decodable {
    @Relationship(inverse: \Artist.albums)
    var artists: Set<Artist>
}

Still need to check if everything connects properly on context save.

helje5 commented 1 year ago

Yes, just tried it, SwiftData has the same issue. Though I'm not entirely sure why this shouldn't be possible, maybe the compiler tries to lookup the key path during macro expansion and sees the same macro there. Good find!

At least in ManagedModels, you shouldn't don't need to specify the inverse at all, it should fine the inverse by type automagically (if it isn't ambiguous).

helje5 commented 1 year ago

I think the CD modeller asks you to, because if the model is loaded, it doesn't add missing inverses. So it has to be configured properly up front. Both SwiftData and ManagedModels actually discover the inverses programatically.

radianttap commented 1 year ago

Yep. Tested this by importing some data into the model and all the relationships were populated properly.