问题
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