RestKit many to many relationship saves new rows in both join table and null values in main table

I use RestKit to cache data from a remote server locally. In it I have a many to many relationship between Category <<-->> News. The mapping seems to work properly, despite that it also saves null values in my Category table (it saves the correct categories too). Like the image below:

It seems to save 30 null rows, I also have 30 (not null) rows in my join table so there might be a correlation here.

The JSON that I get looks like this: "categories":[{"category_id":1},{"category_id":4}]

I have two custom model objects that inherits from NSManagedObject.

@interface News : NSManagedObject
    [...]
    @property (nonatomic, retain) NSSet *categories;
@end

@interface Category : NSManagedObject
[...]
    @property (nonatomic, retain) NSSet *news;
@end

I use @dynamic on both.

My mappings looks like this:

RKManagedObjectMapping *categoryMapping = [RKManagedObjectMapping mappingForClass:[Category class] inManagedObjectStore:objectManager.objectStore];

categoryMapping.primaryKeyAttribute = @"categoryId";
categoryMapping.rootKeyPath = @"categories";
[categoryMapping mapKeyPath:@"id" toAttribute:@"categoryId"];
[...]

RKManagedObjectMapping* newsMapping = [RKManagedObjectMapping mappingForClass:[News class] inManagedObjectStore:objectManager.objectStore];

newsMapping.primaryKeyAttribute = @"newsId";
newsMapping.rootKeyPath = @"news";
[newsMapping mapKeyPath:@"id" toAttribute:@"newsId"];
[...]

// Categories many-to-many (not fully working yet).
[newsMapping mapKeyPath:@"categories" toRelationship:@"categories" withMapping: categoryMapping];

// Register the mappings with the provider
[objectManager.mappingProvider setObjectMapping:newsMapping forResourcePathPattern:@"[path-to-JSON]"];
[objectManager.mappingProvider setObjectMapping:categoryMapping forResourcePathPattern:@"[path-to-JSON]"];

I fetch the data like this (much like the Twitter RestKit example):

- (id)init
{
    self = [super init];
    if (self) {
        [self loadCategories];
        [self loadCategoriesFromDataStore];

        [self loadNews];
        [self loadNewsFromDataStore];
    }
    return self;
}

- (void)loadCategoriesFromDataStore
{    
    NSFetchRequest* request = [Category fetchRequest];
    NSSortDescriptor* descriptor = [NSSortDescriptor sortDescriptorWithKey:@"categoryId" ascending:YES];
    [request setSortDescriptors:[NSArray arrayWithObject:descriptor]];
    _categories = [Category objectsWithFetchRequest:request];
}

- (void)loadNewsFromDataStore
{    
    NSFetchRequest* request = [News fetchRequest];
    NSSortDescriptor* descriptor = [NSSortDescriptor sortDescriptorWithKey:@"createdAt" ascending:NO];
    [request setSortDescriptors:[NSArray arrayWithObject:descriptor]];
    _news = [News objectsWithFetchRequest:request];
}

- (void)loadCategories 
{
    // Load the object model via RestKit
    RKObjectManager *objectManager = [RKObjectManager sharedManager];
    [objectManager loadObjectsAtResourcePath:@"[link-to-JSON]" delegate:self];
}

- (void)loadNews 
{
    // Load the object model via RestKit
    RKObjectManager *objectManager = [RKObjectManager sharedManager];
    [objectManager loadObjectsAtResourcePath:@"[link-to-JSON]" delegate:self];
}

- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {
    [[NSUserDefaults standardUserDefaults] synchronize];
    [self loadCategoriesFromDataStore];
    [self loadNewsFromDataStore];
}

Any ideas what I'm doing wrong?

Note: It also seems to save 30 rows to the join table when there are 15 News, I don't know if this is the normal behavior for join tables.

Update: It also maps the the wrong category id's in the join table (ie. category 66, a null row).

update 2: JSON get request for my Category {"categories":{[...], "id":1, [...]}

Answers


This line is wrong:

[categoryMapping mapKeyPath:@"id" toAttribute:@"categoryId"];

it should be

[categoryMapping mapKeyPath:@"category_id" toAttribute:@"categoryId"];

EDIT: The object mapping you have will map two JSON formats.

1) {"categories":[{"id":7},{"id":12}]} when you have the resource path @"[path-to-JSON]"

2) {"news":[{"id":5, "categories":[{"id":7}]}]} when you have the resource path @"[path-to-JSON]"

(I presume those actual paths are different by the way)

Anything else, such as the JSON you have posted at the top of your question, will not work. The problem you are seeing is because the primary key attribute can not be found in your JSON, so when the object is saved to core data a new entity is created with no primary key.


Need Your Help

set folder into directory

php file-upload

I am creating an apps for uploading file into the system but here, i am facing a problem. the folder have been create properly as i want but when i click the upload button, the file is not save in ...

DynamicMapService on GoogleEarth?

dynamic-data kml google-earth google-earth-plugin arcgis-server

can anyone tell me if it is possible to display an ArcGIS dynamicMapService on GoogleEarth via the GoogleMaps API? It works fine with KML but my services are only visible on the 2D maps.