Connecting Across 1-to-Many (Not Many-to-1) Relationships

218 views
Skip to first unread message

Dave Thompson

unread,
Feb 13, 2012, 6:50:04 AM2/13/12
to RestKit
All,

Blake et al - superb framework and superb documentation. Thanks. The
following question on relationship connections is similar to one asked
previously by Gregory Combs, but sadly that didn't have a conclusive
answer. So here goes:

Sku and OrderComponent are two entities connected by a one to many
relationship. The relationship exists in Core Data as usual, and is
duplicated by an explicit foreign key property from OrderComponent to
Sku, as follows:

Sku:
------
SkuID (PK)

OrderComponent:
------------------------
OrderComponentID (PK)
SkuID (FK)

The iOS app receives two distinct JSON payloads, one containing Skus
and the other containing OrderComponents. The Sku payload contains
only SkuIDs (as well as other attributes which are outside the scope
of this question). The OrderComponent payload contains both
OrderComponentIDs and the corresponding SkuIDs for linking to. There
is no nested data in either payload.

I have two scenarios:

(1) The Sku payload arrives first, followed by the OrderComponent
payload.
(2) The OrderComponent payload arrives first, followed by the Sku
payload.

In both scenarios, I would like to connect the Skus / OrderComponents
to any existing OrderComponents / Skus, based on the SkuID which is
present in both payloads. In scenario (1), I'm able to do this
successfully using the following code:

[orderComponentObjectMapping hasOne:@"sku"
withMapping:skuObjectMapping];
[orderComponentObjectMapping connectRelationship:@"sku"
withObjectForPrimaryKeyAttribute:@"skuID"];

However, in scenario (2) I'm not able to make the connection, nor am I
clear on how or whether it can be done. In scenario (1), it's possible
because there is a foreign key on OrderComponent called skuID, which
points to the primary key on Sku. In scenario (2), this same mechanism
isn't applicable, as there is no foreign key from Sku back to
OrderComponent. Due to the nature of the relationship (1-to-many
rather than many-to-1), it is also not possible to add a foreign key.

Am I missing something trivial, or should I write custom code to
handle this scenario within didLoadObjects or similar?

Thanks to everyone for your great work on RestKit,
Dave

Shane Zatezalo

unread,
Feb 13, 2012, 9:08:03 AM2/13/12
to res...@googlegroups.com
So you are concerned about, via the second method:
- an OrderComponent being created within the Core Data Store that has a NULL SKU
- later that SKU being created, but it is not linked, in Core Data, to any orderComponents.

You have a OrderComponent which hasOne SKU.
You have a SKU which hasMany OrderComponents.

If your mapping is:

> [orderComponentObjectMapping hasOne:@"sku"
> withMapping:skuObjectMapping];
> [orderComponentObjectMapping connectRelationship:@"sku"
> withObjectForPrimaryKeyAttribute:@"skuID"];

And your Core Data Entity has OrderComponent.SKU -> SKU (singular) and
SKU.OrderComponents => OrderComponent.SKU (has many)

When you create an orderComponent object via Restkit, it'll create the object in the Core Data Store with orderComponent pointing to a NULL SKU. Though that orderComponent would intact have orderComponent.SkuID as a valid FK to a nonexistent SKU object.

It seems like if you are going to do #2, you have to do a secondary check (after all orderComponents are created) for any orderComponents w/ a null SKU. Then see if a SKU with that SkuID exists. And if so, set orderComponent.sku = [Sku objectWithId: SkuID]

to create that relationship "afterward" by hand. If Restkit has a way to handle such automatically (and it may) I've not come across it. I think there's a branch or someone who's done some work with "syncing", you might want to search the google group. Their work may include something that would catch such a relationship setup and update it for you.

Shane

Dave Thompson

unread,
Feb 13, 2012, 9:57:48 AM2/13/12
to RestKit
Shane,

Thanks for the prompt reply. I've taken a look through the mails on
syncing - there's definitely some useful background info there.

I'll push ahead with a little custom code within didLoadObjects,
setting orderComponent.sku = [Sku objectWithId: SkuID] where
applicable, as you suggest. It's good to know I wasn't missing
anything obvious before going down that route.

Thanks again,
Dave

Bob Spryn

unread,
Feb 15, 2012, 1:00:15 PM2/15/12
to RestKit
FYI, blake just added support for hydrating to-many relationships:
https://github.com/RestKit/RestKit/commit/789b0b99eb95c1c8f9f8bbf26638bf3a64d7a852

Blake Watters

unread,
Feb 15, 2012, 7:08:51 PM2/15/12
to res...@googlegroups.com
To handle your second scenario, you could probably factor the connection hydration code out of the RKManagedObjectMappingOperation and into a more reusable place, then trigger all the relationship connections manually once all payloads were processed. The connections are dependent on the objects rather than the JSON payloads for this reason (I've just never needed to do it).

--
Blake Watters
VP Engineering, GateGuru
Mobile: 919.260.3783
Get GateGuru for iOS: bit.ly/ggitunes
Get GateGuru for Android: bit.ly/ggandroid

Interested in creating the mobile travel experience of the future? We're hiring!

Reply all
Reply to author
Forward
0 new messages