Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inverse relationship mapping #53

Open
valeriomazzeo opened this issue Nov 17, 2015 · 4 comments
Open

Inverse relationship mapping #53

valeriomazzeo opened this issue Nov 17, 2015 · 4 comments

Comments

@valeriomazzeo
Copy link

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.

@Anviking
Copy link
Owner

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

@valeriomazzeo
Copy link
Author

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?

@Anviking
Copy link
Owner

How do you mean?

@Anviking
Copy link
Owner

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)

@Anviking Anviking modified the milestone: v1.0 Jul 9, 2016
@Anviking Anviking modified the milestone: v0.5 Sep 7, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants