Decodable
Decodable copied to clipboard
Inverse relationship mapping
How would you map an inverse relationship using decodable?
Think of the following scenario:
A <-->> B
With A
being in a to-many
relationship with B
and B
being in a to-one
relationship with A
.
When trying to decode A
(assuming an array of B
objects are contained in the payload), the decoding of B
will be triggered as well.
I can't think of a way using decodable for populating the B
's A
reference (inverse relationship).
In theory all will be needed is to pass Self
(A
) to the mapping of B
(in the decode
function is the only thing I can think of), then having B
recognise that object, maybe as root
or parent
and assign it to the A
's reference it holds.
decodeArray
can be used since it takes takes a elementDecodeClosure
class A: Decodable {
var array: [B] = []
required init(json: AnyObject) throws {
self.array = try decodeArray(B.decode(a: self))(json: json)
}
static func decode(json: AnyObject) throws -> Self {
return try self.init(json: json)
}
}
class B {
weak var a: A?
let name: String
required init(name: String) {
self.name = name
}
static func decode(a a: A)(json: AnyObject) throws -> Self {
let b = try self.init(name: String.decode(json))
b.a = a
return b
}
}
let array: NSArray = ["San Fransisco", "Sparks", "Snow"]
let a = try A.decode(array)
a === a.array[1].a
What if it's not an array and just a one-to-one
relationship?
Can't we have an overloaded version of
public static func decode(j: AnyObject) throws -> NSDictionary {
that takes an elementDecodeClosure
as well?
How do you mean?
Oh, sorry, was confused by the latter part. You perhaps figured it out by now, but with one-to-one relationships we can just write a custom decode or init function for B
(still not Decodable
). In this case, if we're not using it with decodeArray
, the function does not need to be curried.
But in the (curried) example above it would be:
// Instead of: self.array = try decodeArray(B.decode(a: self))(json: json)
self.b = try B.decode(a: self)(json: json)
And without currying, perhaps this order would be nicer:
self.b = try B.decode(json, a: self)