RestKit 多对多关系在连接表中保存新行,在主表中保存空值
Posted
技术标签:
【中文标题】RestKit 多对多关系在连接表中保存新行,在主表中保存空值【英文标题】:RestKit many to many relationship saves new rows in both join table and null values in main table 【发布时间】:2012-06-27 13:39:00 【问题描述】:我使用 RestKit 在本地缓存来自远程服务器的数据。在其中,我在类别 > 新闻之间有多对多的关系。映射似乎工作正常,尽管它还在我的类别表中保存了空值(它也保存了正确的类别)。如下图:
似乎保存了 30 个空行,我的连接表中也有 30 个(非空)行,因此这里可能存在相关性。
我得到的 JSON 如下所示:"categories":["category_id":1,"category_id":4]
我有两个继承自 NSManagedObject
的自定义模型对象。
@interface News : NSManagedObject
[...]
@property (nonatomic, retain) NSSet *categories;
@end
@interface Category : NSManagedObject
[...]
@property (nonatomic, retain) NSSet *news;
@end
我在两者上都使用@dynamic
。
我的映射如下所示:
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]"];
我像这样获取数据(很像 Twitter RestKit 示例):
- (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];
任何想法我做错了什么?
注意: 当有 15 个新闻时,它似乎也将 30 行保存到连接表中,我不知道这是否是连接表的正常行为。
更新:它还映射了连接表中错误的类别 ID(即类别 66,空行)。
更新 2: JSON 获取我的类别 "categories":[...], "id":1, [...]
的请求【问题讨论】:
你能用下面这行告诉我它返回的数字是多少:NSNumber* count = [Category numberOfEntities];。如果返回 30,那么一切都很好。忘记关系(连接)表,如果您的映射正确,核心数据应该正确管理它。 NSNumber* news = [News numberOfEntities] 也应该是 15。 News 返回 15,并且似乎有效。但是类别第一次(在干净的数据库上)返回 36(JSON 中应该有 6 个类别),我第二次运行它是 66 等等。并且值为 NULL。 【参考方案1】:这一行是错误的:
[categoryMapping mapKeyPath:@"id" toAttribute:@"categoryId"];
应该是
[categoryMapping mapKeyPath:@"category_id" toAttribute:@"categoryId"];
编辑: 您拥有的对象映射将映射两种 JSON 格式。
1) "categories":["id":7,"id":12] 当你有资源路径@"[path-to-JSON]"
2) "news":["id":5, "categories":["id":7]] 当你有资源路径 @"[path-to-JSON]"
(顺便说一下,我认为这些实际路径是不同的)
任何其他内容(例如您在问题顶部发布的 JSON)都不起作用。您看到的问题是因为在您的 JSON 中找不到主键属性,所以当对象保存到核心数据时,会创建一个没有主键的新实体。
【讨论】:
嗯,我不确定,id 是我的 JSON 中的 PK,它映射到我数据库中的 categoryId,然后 categoryId 也用作 RestKit 的 primaryKeyAttribute,以防止重复。 没有你的 JSON 是这个 "categories":["category_id":1,"category_id":4]。 category_id 是要映射到核心数据 PK categoryId 的服务器 PK 的关键路径。 是的,但这是我的新闻 JSON 请求中的外键,在类别请求中,PK 看起来像这样:... "id":1 ...
,我映射到。
那么您在问题中发布的 JSON 是错误的。请为这两个请求发布 JSON。如果每个PK都不一样,你需要两张不同的地图。
好的,我已将 JSON 添加到我原来的问题中。以上是关于RestKit 多对多关系在连接表中保存新行,在主表中保存空值的主要内容,如果未能解决你的问题,请参考以下文章