Skip to content

Commit 8a2896e

Browse files
committed
Fixed decoding to-many relationships
1 parent a5beb76 commit 8a2896e

1 file changed

Lines changed: 26 additions & 2 deletions

File tree

Sources/CoreModel/Decoder.swift

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ extension Entity where Self: Decodable {
3131
userInfo: userInfo,
3232
log: log
3333
)
34-
log?("Will decode \(model.entity) \(model.id))")
34+
log?("Will decode \(model.entity) \(model.id)")
3535
try self.init(from: decoder)
3636
}
3737
}
@@ -183,16 +183,40 @@ internal extension ModelDataDecoder {
183183
}
184184

185185
func decodeDecodable<T: Decodable> (_ type: T.Type, forKey key: CodingKey) throws -> T {
186+
let property = PropertyKey(key)
186187
// override for native types and id
187188
if key.stringValue == identifierKey {
189+
log?("Will decode \(type) at path \"\(codingPath.path)\"")
188190
guard let convertible = type as? ObjectIDConvertible.Type else {
189-
throw DecodingError.typeMismatch(ObjectIDConvertible.self, DecodingError.Context(codingPath: codingPath, debugDescription: "Cannot decode identifer from \(type). Types used as identifiers must conform to \(String(describing: ObjectID.self))"))
191+
throw DecodingError.typeMismatch(ObjectIDConvertible.self, DecodingError.Context(codingPath: codingPath, debugDescription: "Cannot decode identifer from \(type). Types used as identifiers must conform to \(String(describing: ObjectIDConvertible.self))"))
190192
}
191193
let id = self.data.id
192194
guard let value = convertible.init(objectID: id) else {
193195
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: codingPath, debugDescription: "Cannot decode \(type) from identifier \(id)"))
194196
}
195197
return value as! T
198+
} else if let relationship = relationships[property] {
199+
log?("Will decode \(type) at path \"\(codingPath.path)\"")
200+
guard let relationshipValue = self.data.relationships[property] else {
201+
throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "Missing relationship value for \(key.stringValue)"))
202+
}
203+
switch (relationship.type, relationshipValue) {
204+
case (_, .null):
205+
//assertionFailure()
206+
throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "Expected \(type) value for \(key.stringValue)"))
207+
case (.toMany, .toMany):
208+
return try T.init(from: self)
209+
case (.toOne, .toOne(let objectID)):
210+
guard let convertible = type as? ObjectIDConvertible.Type else {
211+
throw DecodingError.typeMismatch(ObjectIDConvertible.self, DecodingError.Context(codingPath: codingPath, debugDescription: "Cannot decode identifer from \(type). Types used as identifiers must conform to \(String(describing: ObjectIDConvertible.self))"))
212+
}
213+
guard let value = convertible.init(objectID: objectID) else {
214+
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: codingPath, debugDescription: "Cannot decode \(type) from identifier \(objectID)"))
215+
}
216+
return value as! T
217+
default:
218+
throw DecodingError.typeMismatch(type, DecodingError.Context(codingPath: codingPath, debugDescription: "Cannot decode relationship from \(type)."))
219+
}
196220
} else if let decodableType = type as? AttributeDecodable.Type {
197221
return try decodeAttribute(decodableType, forKey: key) as! T
198222
} else {

0 commit comments

Comments
 (0)