RestKit: connecting many-to-many relationship

2019-08-27 21:37发布

问题:

I've got the following Core Data model is my app:

+--------------------+         +-------------+
| Ingredient         |         | Dish        |
+--------------------+         +-------------+
| id                 |         | id          |
| title              |         | title       |
| dishId (transient) |
+--------------------+         +-------------+
| dishes             | <<--->> | ingredients |
+--------------------+         +-------------+

I also have a webservice, which allows me to request all ingredients for a given dish like this:

/dish/1/ingredients

(where 1 is some dish id).

The request to such response is as follows:

{
    { "id": "1", "title": "milk" },
    { "id": "2", "title": "egg" },
    { "id": "3", "title": "flour" }
}

I've read about RKConnectionDescription, but I can't figure out how to use it to connect these two entities in this particular case.

Here's the mapping I've got so far:

RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:@"Ingredient" inManagedObjectStore:store];

[mapping setIdentificationAttributes:@[@"id"]];

[mapping addAttributeMappingsFromDictionary:@{
        @"id" : @"id",
        @"title" : @"title",
        @"@metadata.dishId" : @"dishId"
}];

UPDATE

I've added a new transient property dishId to my Ingredient entity and tried to set up connection like this:

NSEntityDescription *entityDescription =
        [NSEntityDescription entityForName:@"Ingredient" inManagedObjectContext:mainContext];
NSRelationshipDescription *relationship =
        [entityDescription relationshipsByName][@"dishes"];
RKConnectionDescription *connection =
        [[RKConnectionDescription alloc] initWithRelationship:relationship attributes:@{
                @"dishId" : @"id"
        }];

[mapping addConnection:connection];

but each time I request ingredients for another dish, it replaces old connections with a new ones, so I basically get one-to-one relationship. For example, I first request ingredients for omelette, and it connects omelette to eggs, milk and flour. Then I request ingredients for pancakes, and it connects pancakes to eggs, milk and flour, however omelette connection to these ingredients is lost.

assignmentPolicy is not available on RKConnectionDescription.

回答1:

You want to use RKRoute to create the request path and to provide you with the required relationship mapping (you don't need to do it yourself). You need to set the path pattern for the route to /dish/:id/ingredients so that the identity is pulled from the Dish and injected.

Use routeWithRelationshipName:objectClass:pathPattern:method: to create the route.

Use getObjectsAtPathForRelationship:ofObject:parameters:success:failure: to get the contents.

Once you have the route connected, any mapping that it does will be provided with the URL content metadata. So, in your mapping you use:

@"@metadata.routing.parameters.id" : @"dishId"

Note that dishId is a new transient attribute added to Ingredient that you use in your foreign key mapping (RKConnectionDescription).