2

新しいRestKit0.9.3のRKCatalogの例を使用しようとしています。RKRelationshipMappingExampleでは、作成者はタスクとユーザーの間に接続コードを追加するのを忘れていますが、追加した後でも正しく機能しません。

{"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結論: 1 対多のマッピングの問題 (オブジェクトの の逆ハイドレーションのコンテキストでここで説明tasks) は0.9.3で壊れています。2012 年 3 月 8 日時点での開発ブランチのプルにより、問題がそこで修正されていることが確認されました -- Blake は issue #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 日前のマスターからのプルに対して実行されました。

于 2012-02-21T21:28:00.567 に答える
1

user -> task マッピングは、userMapping の行で設定されます[userMapping mapRelationship:@"tasks" withMapping:taskMapping];。逆は作成されなかったと言っていると思いますか?

それが問題である場合、私はまだ試していませんが、このコミットで問題が修正されることがわかると思います。(その時点でツリーをプルするか、現在のマスター ブランチをプルすることをお勧めします)。

それはさておき、[taskMapping connectRelationship:@"assignedUser" withObjectForPrimaryKeyAttribute:@"assignedUserID"];「割り当てられたユーザー ID」の主キー属性を持つオブジェクトを検索している行に問題がありますが、他のマッピングを見ると、そのようなオブジェクトは存在しません。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 時間半近くいじり続け、ついに機能するようになりました。私が行った手順: 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 に答える