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

醉酒当歌 提交于 2019-12-12 03:43:02

问题


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, [...]}


回答1:


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.



来源:https://stackoverflow.com/questions/11227548/restkit-many-to-many-relationship-saves-new-rows-in-both-join-table-and-null-val

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!