【问题标题】:Map only on element of a one to many relationships仅映射一对多关系的元素
【发布时间】:2014-08-11 13:58:53
【问题描述】:

我遇到了以下问题。我在EventComment 之间有一个关系 one_to_many。一个Event 可以有多个Comment,但一个Comment 只属于一个Event

到这里为止,一切都很好。现在,当我添加评论时,我只想映射这个新评论。这意味着我正在使用从CommentMoment 的关系。

我遇到了一些我无法解决的映射问题。在所有描述之后,我的错误在这篇文章的末尾。

我正在接收这个 JSON:

"comment": {
    "id": 17,
    "commentable_id": 12,
    "commentable_type": "Moment",
    "content": "That's it ! ",
    "created_at": "2014-06-20T18:17:42Z",
    "updated_at": "2014-06-20T18:17:42Z",
    "user_id": 1,
    "creator": {
        "id": 1,
        "email": "test@test.com",
        "firstname": "Bobby",
        "lastname": "Stouket",
        "gender": 0,
        "created_at": "2014-04-06T17:48:11Z",
        "updated_at": "2014-06-20T18:17:26Z"
    }
}

这是我的评论映射:

RKEntityMapping *commentMapping = [RKEntityMapping mappingForEntityForName:@"Comment" inManagedObjectStore:store];
commentMapping.identificationAttributes = @[ @"commentId"];
[commentMapping addAttributeMappingsFromDictionary:@{
                                                     @"id" : @"commentId",
                                                     @"updated_at": @"updatedAt",
                                                     @"created_at": @"createdAt",
                                                     @"user_id": @"userId",
                                                     @"commentable_id": @"commentableId",
                                                     @"commentable_type": @"commentableType",
                                                     @"content": @"content"
                                                     }];

RKEntityMapping *userCreatorMapping = [APICallUser RKGetUserMappingOnlyWithAvatarForManagedObjectStore:store];
[commentMapping addConnectionForRelationship:@"creator" connectedBy:@{@"userId": @"userId"}];
[commentMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"creator"
                                                                              toKeyPath:@"creator"
                                                                            withMapping:userCreatorMapping]];

这是我的时刻映射代码(与正在工作的 cmets 的关联):

RKEntityMapping *momentMapping = [RKEntityMapping mappingForEntityForName:@"Moment" inManagedObjectStore:store];
momentMapping.identificationAttributes = @[ @"momentId"];
[momentMapping addAttributeMappingsFromDictionary:@{
                                                          @"id" : @"momentId",
                                                          @"creator.id" : @"creatorId",
                                                          @"created_at" : @"createdAt",
                                                          @"updated_at" : @"updatedAt"
                                                          }];

RKEntityMapping *commentMapping = [APICallComment RKGetCommentMappingForManagedObjectStore:store];
[commentMapping addConnectionForRelationship:@"moment" connectedBy:@{@"commentableId":@"momentId"}];
[momentMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"comments"
                                                                              toKeyPath:@"comments"
                                                                            withMapping:commentMapping]];

还有一件事需要知道的是,评论可以针对某一时刻或一张照片。根据我的 JSON,我认为我不需要 RKDynamicMapping,但我不确定。

这是我使用映射时的代码。请求发送成功,收到之前写的JSON。

KEntityMapping *commentMapping = [APICallComment RKGetCommentMappingForManagedObjectStore:self.appDelegate.managedObjectStore];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:commentMapping
                                                                                        method:RKRequestMethodPOST
                                                                                   pathPattern:APICallCommentCreateCommentsRouteName
                                                                                       keyPath:@"comment"
                                                                                   statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[session.objectManager addResponseDescriptor:responseDescriptor];
//session.objectManager.requestSerializationMIMEType=RKMIMETypeJSON;

Error Domain=org.restkit.RestKit.ErrorDomain Code=1001 “在搜索的关键路径中找不到可映射的对象表示。” UserInfo=0xb8a9150 {DetailedErrors=(), NSLocalizedFailureReason=映射操作无法在搜索的关键路径找到任何嵌套对象表示:cmets、device、devices 发现输入到映射器的表示在以下关键路径中包含嵌套对象表示: 这可能表明您为映射配置了错误的关键路径。, NSLocalizedDescription=在搜索的关键路径中找不到可映射的对象表示。, keyPath=null}

编辑: 这是代码行session.objectManager.requestDescriptor 的结果。这真的很奇怪。我在NSArray 中只能看到 1 个对象。当我打印它时,我可以阅读:

Printing description of $1:
<__NSArrayI 0xbd61010>(
<RKRequestDescriptor: 0xbd12bb0 method=(POST) objectClass=BasicLocation rootKeyPath=position :      <RKObjectMapping:0xbd40b70 objectClass=NSMutableDictionary propertyMappings=(
"<RKAttributeMapping: 0xbd545d0 latitude => lat>",
"<RKAttributeMapping: 0xbd58430 longitude => lng>"
)>>
)

我没有写过position应该是rootKeyPath,而我的其他属性不在这里(内容、commentableType、userId、createdAt、updatedAt、commentId)。

感谢您的帮助。

【问题讨论】:

  • 您显示 JSON 以供评论,但不是时刻 - 显示。日志消息表明您显示的代码不是您拥有的代码 - 关键路径不匹配(或者您只是在创建响应描述符后未能添加它)。考虑使用多个响应描述符来分离您的“创建者”映射处理...
  • JSON 是我在创建新评论后收到的。这里暂时没有 JSON。唯一有comments 关联的地方是我的时刻映射,但我没有使用它。然后我迷路了。我还不熟悉多重响应描述符。

标签: ios objective-c json mapping restkit


【解决方案1】:

你创造:

RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:commentMapping
                                                                                    method:RKRequestMethodPOST
                                                                               pathPattern:APICallCommentCreateCommentsRouteName
                                                                                   keyPath:@"comment"
                                                                               statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];

但你永远不能将它添加到对象管理器中,因为它只理解comments, device, devices

这似乎是你的主要问题。

你通常不会这样做:

[commentMapping addConnectionForRelationship:@"creator" connectedBy:@{@"userId": @"userId"}];
[commentMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"creator"
                                                                          toKeyPath:@"creator"
                                                                        withMapping:userCreatorMapping]];

因为您为完全相同的内容和关系提供了 2 个不同的映射,而您只需要一个,因为用户信息嵌套在评论信息中。因此,您可以删除外键映射 (addConnectionForRelationship:)。

【讨论】:

  • 我认为addConnectionForRelationship 是在说哪些属性用于模型之间的匹配/链接。如果我只使用addPropertyMappingRestkit 将如何知道使用哪些属性?
  • addConnectionForRelationship 用于外键映射,因此数据不嵌套。如果它是嵌套的,那么您提供给 relationshipMappingFromKeyPath: 的映射提供了要匹配的唯一标识,并且嵌套提供了连接上下文。
  • 我错了,明明是[userCreatorMapping addConnectionForRelationship..]
  • 但是为什么我不能将我的描述符添加到对象管理器中呢?那么,我的对象管理器是如何理解comment 的呢?我仍然对这些映射有点迷茫。
  • 可以并且应该添加响应描述符,但似乎没有,因为对象管理器只理解 cmets、device 和 devices -- 而不是comment
【解决方案2】:

映射很好,但错误来自这里:

[RKResponseDescriptor responseDescriptorWithMapping:commentMapping
                                             method:RKRequestMethodGET
                                        pathPattern:HERE
                                            keyPath:@"comment"
                                        statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];

路径模式不是我写的。这个变量发生了变化,一切正常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多