Skip to content

Fix relationship on different contexts error when nested objects are inserted #107

Closed
wants to merge 5 commits into from

4 participants

@tsakoyan

This is a fix only concerning inserting non-existing nested objects before save, and persisting root and nested objects from the response.

Tsakogiannis... added some commits Nov 7, 2012
@mattt
mattt commented Dec 13, 2012

Hi, @tsakoyan. Thanks for your pull request—my apologies for taking so long to review it.

I was hoping you could help clarify what this code fixes, and tell me a little more about what's going on in the code. There seems to be a lot of similar-looking code in -insertOrUpdateObjectsFromRepresentations:ofEntity:fromResponse:withContext:error:completionBlock:; is there any way that your patch could be refactored to use this function? Likewise with -updateBackingObject:withAttributeAndRelationshipValuesFromManagedObject:; is there any overlap there?

@tsakoyan

No apologies needed, I also preferred to wait until the other pull request for relationship on different contexts got merged, before I could come up with a more elegant solution.
My special case is the posting of nested objects creating 2-3 objects on the other side with one request.
The main entity gets inserted and POSTed by AFIS (as a representation of the whole tree) and the "sub"-entities are ignored (with an invalid request url, because I don't want to save them with a nil return of - (NSMutableURLRequest *)requestForInsertedObject:(NSManagedObject *)insertedObject; -- maybe I should add a way to ignore an object insert all together).
The response contains the full created tree, and I need to "parse" any incoming added data (e.g. UDIDs created server side) and persist the tree in the backing context.

-insertOrUpdateObjectsFromRepresentations:ofEntity:fromResponse:withContext:error:completionBlock: 

has the main effect of inserting the objects as new (either only the nested ones or all of them) when I already have them as inserted and connected to the main object being "updated" by the response from the server.
So long story short I only need the backing-context part of that method...

If you would like such behavior I'll put more effort to it (like refactoring backing context insertion out of the insertOrUpdate to use it there as well)

p.s. updateBackingObject wouldn't work as well because there aren't any backing objects yet to update

Tsakogiannis... added some commits Jan 3, 2013
Tsakogiannis, Christos Handling nested objects in insert response more elegantly 3260e99
Tsakogiannis, Christos Refactoring response handling by executeSaveChanges -insert case- in …
…AFIncrementalStore to do recursive nested-object update from the returned representation instead of just for the root-object
7d55124
Tsakogiannis, Christos Obtain permamentId for inserted object before recursive looping into …
…updating its children, otherwise they will not set the relationship on a temporary objectID'ed object
2610369
@adamhowardprice

I'm interested in this as a solution to a common behavior too. @mattt, do you think this is applicable?

@tsakoyan

Sorry for not commenting earlier, what I did in the last commits is actually use the, then, latest merge which spawned the

// tackles correctly connecting the created backing object with the already existing related objects 
- (void)updateBackingObject:(NSManagedObject *)backingObject
withAttributeAndRelationshipValuesFromManagedObject:(NSManagedObject *)managedObject

but took out the parsing of the response, the representationOfAttributes along with the af_resourceIdentifier setting out of the

- (id)executeSaveChangesRequest:(NSSaveChangesRequest *)saveChangesRequest
                    withContext:(NSManagedObjectContext *)context
                          error:(NSError *__autoreleasing *)error

and put it in a new

- (void)updateObject:(NSManagedObject *)object withAttributeAndRelationshipValuesFromRepresentation:(NSDictionary *)representation andResponse:(NSHTTPURLResponse *)response {

that also reads the relationship objects (like the fetchRequest does) and calls itself recursively with their representation.
So if the response contains nested objects it creates/updates them in the backingContext accordingly connecting them to their parents in the backingContext, and leaves the other relations as they were (responsibility of updateBackingObject:withAttributeAndRelationshipValuesFromManagedObject:)

That said, the problem is I didn't address the problem of similar scenario in the updateObject case, where the root object is updated but its nested objects are created/updated as well. Unfortunately I didn't have the time/use cases to tackle that one appropriately...

@max-horvath

@mattt, any comment on whether this is an acceptable solution or not?

@mattt
mattt commented Nov 18, 2014

As of e8c6472, AFIncrementalStore is no longer being actively maintained. Thank you for your contributions; my sincere apologies for any inconvenience this may have caused.

@mattt mattt closed this Nov 18, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.