2

我正在尝试使用来自新 RestKit 0.9.3 的示例 RKCatalog。在 RKRelationshipMappingExample 中,创建者忘记在 Task 和 User 之间添加连接代码,但即使添加后也无法正常工作。

{"project": {
    "id": 123,
    "name": "Produce RestKit Sample Code",
    "description": "We need more sample code!",
    "user": {
        "id": 1,
        "name": "Blake Watters",
        "email": "blake@twotoasters.com"
    },
    "tasks": [
        {"id": 1, "name": "Identify samples to write", "assigned_user_id": 1},
        {"id": 2, "name": "Write the code", "assigned_user_id": 1},
        {"id": 3, "name": "Push to Github", "assigned_user_id": 1},
        {"id": 4, "name": "Update the mailing list", "assigned_user_id": 1}
    ]
}}

[taskMapping connectRelationship:@"assignedUser" withObjectForPrimaryKeyAttribute:@"assignedUserID"];

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        RKObjectManager* objectManager = [RKObjectManager objectManagerWithBaseURL:gRKCatalogBaseURL];
        objectManager.objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:@"RKRelationshipMappingExample.sqlite"];

        RKManagedObjectMapping* taskMapping = [RKManagedObjectMapping mappingForClass:[Task class]];
        [taskMapping mapKeyPath:@"id" toAttribute:@"taskID"];
        [taskMapping setPrimaryKeyAttribute:@"taskID"];
        [taskMapping mapKeyPath:@"name" toAttribute:@"name"];
        [taskMapping mapKeyPath:@"assigned_user_id" toAttribute:@"assignedUserID"];
        [taskMapping connectRelationship:@"assignedUser" withObjectForPrimaryKeyAttribute:@"assignedUserID"];
        [objectManager.mappingProvider setMapping:taskMapping forKeyPath:@"task"];

        RKManagedObjectMapping* userMapping = [RKManagedObjectMapping mappingForClass:[User class]];
        [userMapping mapAttributes:@"name", @"email", nil];
        [userMapping mapKeyPath:@"id" toAttribute:@"userID"];
        [userMapping setPrimaryKeyAttribute:@"userID"];
        [userMapping mapRelationship:@"tasks" withMapping:taskMapping];
        [objectManager.mappingProvider setMapping:userMapping forKeyPath:@"user"];

        // NOTE - Project is not backed by Core Data
        RKObjectMapping* projectMapping = [RKObjectMapping mappingForClass:[Project class]];
        [projectMapping mapKeyPath:@"id" toAttribute:@"projectID"];
        [projectMapping mapAttributes:@"name", @"description", nil];
        [projectMapping mapRelationship:@"user" withMapping:userMapping];
        [projectMapping mapRelationship:@"tasks" withMapping:taskMapping];
        [objectManager.mappingProvider setMapping:projectMapping forKeyPath:@"project"];
    }

    return self;
}

我做的一切都好吗?-- 它不通过用户 ID 将任务连接到用户。

4

3 回答 3

2

更新:我应该更仔细地阅读Blake 的链接帖子——它会更快地将我指向开发分支。

底线:一对多的映射问题(这里在User对象的逆水合的上下文中讨论)在 0.9.3 中tasks打破。截至 2012 年 3 月 8 日,开发分支的拉动确认该问题已在此处解决——布莱克在问题 #284 中解决了该问题。您仍然需要添加示例不包含的逻辑connectRelationship:withObjectForPrimaryKeyAttribute:


@Evan,感谢您提供的提示RKLogConfigureByName("RestKit/ObjectMapping", RKLogLevelTrace)- 它有助于分析实际发生​​的情况。

我仍然非常处于 RestKit 的“寻找我的方式”阶段,所以 YMMV。但是,根据Blake 的这篇文章,实际上看起来你需要两者——这是我可以让示例工作的唯一方法。但是,对相关对象的主键的引用是使用它的本地 [即,任务的 ivar] 属性来引用的:

        RKManagedObjectMapping* taskMapping = [RKManagedObjectMapping mappingForClass:[Task class]];
        [taskMapping mapKeyPath:@"id" toAttribute:@"taskID"];
        [taskMapping mapKeyPath:@"name" toAttribute:@"name"];
        [taskMapping mapKeyPath:@"assigned_user_id" toAttribute:@"assignedUserID"];
        taskMapping.primaryKeyAttribute = @"taskID";

        RKManagedObjectMapping* userMapping = [RKManagedObjectMapping mappingForClass:[User class]];
        [userMapping mapAttributes:@"name", @"email", nil];
        [userMapping mapKeyPath:@"id" toAttribute:@"userID"];
        [userMapping mapRelationship:@"tasks" withMapping:taskMapping];
        userMapping.primaryKeyAttribute = @"userID";
        [objectManager.mappingProvider setMapping:userMapping forKeyPath:@"user"];

        [taskMapping mapRelationship:@"assignedUser" withMapping:userMapping];
        [taskMapping connectRelationship:@"assignedUser" withObjectForPrimaryKeyAttribute:@"assignedUserID"];
        [objectManager.mappingProvider setMapping:taskMapping forKeyPath:@"task"]; 

这与大约 3 天前的 master 的拉动相反。

于 2012-02-21T21:28:00.567 回答
1

用户 -> 任务映射是在 userMapping 上设置的,带有[userMapping mapRelationship:@"tasks" withMapping:taskMapping];. 我假设您是说没有创建逆?

如果这是问题所在,我想你会发现这个提交解决了这个问题,尽管我自己还没有尝试过。(你可以在那个时候拉树,或者更好的是,拉当前的主分支)。

除此之外,您对它[taskMapping connectRelationship:@"assignedUser" withObjectForPrimaryKeyAttribute:@"assignedUserID"];正在搜索具有“assignedUserID”主键属性的对象这一行有问题,但是查看其他映射,不存在这样的对象。请注意,在 userMapping 上,主键定义为[userMapping setPrimaryKeyAttribute:@"userID"];

你可能想要[taskMapping connectRelationship:@"assignedUser" withObjectForPrimaryKeyAttribute:@"userID"];,甚至更好[taskMapping mapRelationship:@"assignedUser" withMapping:userMapping];

(通过我链接的提交,我什至不确定是否有必要添加任何东西来获得相反的结果——你可以同时尝试看看。)

如果仍有问题,您可以使用以下命令打开 ObjectMapper 的日志RKLogConfigureByName("RestKit/ObjectMapping", RKLogLevelTrace);

于 2011-09-07T14:31:03.297 回答
1

我一直在弄乱这段代码近一个半小时,终于让它工作了。我已采取的步骤:1)重新安排创建如下关系 2)取消选中 RKRelationshipMappingExample.xcdatamodel > task.assignedUser 关系的“可选”复选标记。我注意到它既是“可选的”又是最小 1,最大 1。我在此更改后删除了该应用程序并重新安装了它。现在用户被添加到任务和任务到用户!

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        RKObjectManager* objectManager = [RKObjectManager objectManagerWithBaseURL:gRKCatalogBaseURL];
        objectManager.objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:@"RKRelationshipMappingExample.sqlite"];


        RKManagedObjectMapping* taskMapping = [RKManagedObjectMapping mappingForClass:[Task class]];
        [taskMapping mapKeyPath:@"id" toAttribute:@"taskID"];
        [taskMapping mapKeyPath:@"name" toAttribute:@"name"];
        [taskMapping mapKeyPath:@"assigned_user_id" toAttribute:@"assignedUserID"];
        taskMapping.primaryKeyAttribute = @"taskID";

        RKManagedObjectMapping* userMapping = [RKManagedObjectMapping mappingForClass:[User class]];
        [userMapping mapAttributes:@"name", @"email", nil];
        [userMapping mapKeyPath:@"id" toAttribute:@"userID"];

        userMapping.primaryKeyAttribute = @"userID";
        [objectManager.mappingProvider setMapping:userMapping forKeyPath:@"user"];
        [objectManager.mappingProvider setMapping:taskMapping forKeyPath:@"task"];

        [userMapping mapRelationship:@"tasks" withMapping:taskMapping];        
        [taskMapping mapRelationship:@"assignedUser" withMapping:userMapping];

        [taskMapping connectRelationship:@"assignedUser" withObjectForPrimaryKeyAttribute:@"assignedUserID"];


        // NOTE - Project is not backed by Core Data
        RKObjectMapping* projectMapping = [RKObjectMapping mappingForClass:[Project class]];
        [projectMapping mapKeyPath:@"id" toAttribute:@"projectID"];
        [projectMapping mapAttributes:@"name", @"description", nil];
        [projectMapping mapRelationship:@"user" withMapping:userMapping];
        [projectMapping mapRelationship:@"tasks" withMapping:taskMapping];
        [objectManager.mappingProvider setMapping:projectMapping forKeyPath:@"project"];



    }

    return self;
}

//to see NSLog messages, change the LOGGER_DEBUG to 2 (in LoggerClient.m) like this:
#define LOGGER_DEBUG 2
#ifdef NSLog
    #undef NSLog
#endif



//test method to make sure all relationships are created.
- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects {
    _objects = [objects retain];

    for(Project* managedObject in objects)
    {   NSLog(@" project user: %@", [managedObject.user description]);
        NSLog(@"###### user tasks count: %i",[managedObject.user.tasks  count]);
        for(Task* task in managedObject.user.tasks)
        {
            NSLog(@"+++++managedObject.user.tasks: %@", [task description]);
        }

        for(Task* task in managedObject.tasks)
        {
            NSLog(@"*****task: %@", [task description]);
        }

    }
    [self.tableView reloadData];
}
于 2012-03-05T21:43:02.807 回答