如何使用 RestKit 将对象 POST 到 Rails?
我正在尝试使用 RestKit 和 Rails 来实现奇迹。我正在使用 Rails 3.1.1 和 RestKit 0.9.3 (不是 master 分支)。我在 iOS 应用程序中使用 Core Data,因此我尝试将应用程序设置为使用尽可能多的 RestKit 魔法来与 Rails 应用程序交互。
但是,我在尝试将新对象发布到要创建的服务器时遇到问题。我已经成功地获取了这些对象。这是我执行此操作的代码:
RKObjectManager* manager = [RKObjectManager objectManagerWithBaseURL:@"http://IP_ADDRESS"];
manager.objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:@"magikarp.sqlite"];
manager.client.requestQueue.showsNetworkActivityIndicatorWhenBusy = YES;
manager.acceptMIMEType = RKMIMETypeJSON;
manager.serializationMIMEType = RKMIMETypeJSON;
///
/// Setup Routing
///
RKObjectRouter *router = [[RKObjectRouter alloc] init];
[router routeClass:[List class] toResourcePath:@"/lists/(listID)"];
[router routeClass:[List class] toResourcePath:@"/lists" forMethod:RKRequestMethodPOST];
manager.router = router;
///
/// Setup mapping for my "List" object; a subclass of NSManagedObject
///
RKManagedObjectMapping *listMapping = [RKManagedObjectMapping mappingForClass:[List class]];
listMapping.primaryKeyAttribute = @"listID";
[listMapping mapAttributes:@"title", nil];
[listMapping mapKeyPath:@"id" toAttribute:@"listID"];
[manager.mappingProvider setMapping:listMapping forKeyPath:@"list"];
这似乎对我来说效果很好。现在,我想将新创建的对象发布回服务器。
- (void)createList:(NSString *)listName {
List *newList = [List object];
newList.title = listName;
[[RKObjectManager sharedManager] postObject:newList delegate:self];
}
我使用我希望新列表具有的名称来调用此方法。调用此方法,但出现此错误:
2011-12-06 19:24:17.822 Magikarp[13921:14c1b] W restkit.object_mapping:RKObjectMapper.m:74 Adding mapping error: Could not find an object mapping for keyPath: ''
2011-12-06 19:24:17.823 Magikarp[13921:14c1b] E restkit.network:RKObjectLoader.m:190 Encountered errors during mapping: Could not find an object mapping for keyPath: ''
2011-12-06 19:24:17.823 Magikarp[13921:14c1b] Hit error: Error Domain=org.restkit.RestKit.ErrorDomain Code=1001 "Could not find an object mapping for keyPath: ''" UserInfo=0x6bb9da0 {=RKObjectMapperKeyPath, NSLocalizedDescription=Could not find an object mapping for keyPath: ''}
我为完成映射所做的尝试是:(
RKObjectMapping *listSerializationMapping = [RKObjectMapping mappingForClass:[NSMutableDictionary class]];
[listSerializationMapping mapKeyPath:@"title" toAttribute:@"title"];
[listSerializationMapping mapKeyPath:@"ListID" toAttribute:@"id"];
[manager.mappingProvider setSerializationMapping:listSerializationMapping forClass:[List class]];
这给出了上述错误)。我知道有一种非常简单的方法可以做到这一点,但是没有一个示例具有此代码,并且所有文档似乎都已过时...您是否也必须将信息作为 POST 参数发送?帮助将不胜感激,谢谢!
更新
这是服务器响应 - 它可以工作,但参数似乎有点混乱? (我输入的标题是:“由 iPhone 2 制造!”)
Started POST "/lists" for 129.21.86.32 at 2011-12-07 09:34:43 -0500
Processing by ListsController#create as JSON
Parameters: {"id"=>0, "title"=>"Made from the iPhone 2!", "list"=>{"id"=>0, "title"=>"Made from the iPhone 2!"}}
WARNING: Can't verify CSRF token authenticity
WARNING: Can't mass-assign protected attributes: id
(0.3ms) BEGIN
SQL (0.9ms) INSERT INTO "lists" ("created_at", "title", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["created_at", Wed, 07 Dec 2011 14:34:43 UTC +00:00], ["title", "Made from the iPhone 2!"], ["updated_at", Wed, 07 Dec 2011 14:34:43 UTC +00:00]]
(16.4ms) COMMIT
Completed 201 Created in 77ms (Views: 1.8ms | ActiveRecord: 21.9ms)
I'm trying to make the magic happen with RestKit and Rails. I'm using Rails 3.1.1, and RestKit 0.9.3 (not the master branch). I am using Core Data in my iOS app, so I'm trying to setup the app to use as much RestKit magic as possible to interact with the rails app.
However, I'm having a problem trying to POST a new object to my server to be created. I have successfully GET'ed the objects down. Here is my code to do that:
RKObjectManager* manager = [RKObjectManager objectManagerWithBaseURL:@"http://IP_ADDRESS"];
manager.objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:@"magikarp.sqlite"];
manager.client.requestQueue.showsNetworkActivityIndicatorWhenBusy = YES;
manager.acceptMIMEType = RKMIMETypeJSON;
manager.serializationMIMEType = RKMIMETypeJSON;
///
/// Setup Routing
///
RKObjectRouter *router = [[RKObjectRouter alloc] init];
[router routeClass:[List class] toResourcePath:@"/lists/(listID)"];
[router routeClass:[List class] toResourcePath:@"/lists" forMethod:RKRequestMethodPOST];
manager.router = router;
///
/// Setup mapping for my "List" object; a subclass of NSManagedObject
///
RKManagedObjectMapping *listMapping = [RKManagedObjectMapping mappingForClass:[List class]];
listMapping.primaryKeyAttribute = @"listID";
[listMapping mapAttributes:@"title", nil];
[listMapping mapKeyPath:@"id" toAttribute:@"listID"];
[manager.mappingProvider setMapping:listMapping forKeyPath:@"list"];
That seems to be working well for me. Now, I want to POST a newly created object back to the server.
- (void)createList:(NSString *)listName {
List *newList = [List object];
newList.title = listName;
[[RKObjectManager sharedManager] postObject:newList delegate:self];
}
I call this method with the name I want the new list to have. This method is called, but I get this error:
2011-12-06 19:24:17.822 Magikarp[13921:14c1b] W restkit.object_mapping:RKObjectMapper.m:74 Adding mapping error: Could not find an object mapping for keyPath: ''
2011-12-06 19:24:17.823 Magikarp[13921:14c1b] E restkit.network:RKObjectLoader.m:190 Encountered errors during mapping: Could not find an object mapping for keyPath: ''
2011-12-06 19:24:17.823 Magikarp[13921:14c1b] Hit error: Error Domain=org.restkit.RestKit.ErrorDomain Code=1001 "Could not find an object mapping for keyPath: ''" UserInfo=0x6bb9da0 {=RKObjectMapperKeyPath, NSLocalizedDescription=Could not find an object mapping for keyPath: ''}
The attempt I made to get the mapping done was:
RKObjectMapping *listSerializationMapping = [RKObjectMapping mappingForClass:[NSMutableDictionary class]];
[listSerializationMapping mapKeyPath:@"title" toAttribute:@"title"];
[listSerializationMapping mapKeyPath:@"ListID" toAttribute:@"id"];
[manager.mappingProvider setSerializationMapping:listSerializationMapping forClass:[List class]];
(That gives the above error). I know there is a pretty straightforward way to do this, but none of the examples have this code, and all the documentation seems out of date... Do you have to send the info as POST parameters as well? Help would be appreciated, Thank you!
Update
This is the server response - it works, but it appears that the parameters are a bit messed up? (The title I put in was: "Made from the iPhone 2!")
Started POST "/lists" for 129.21.86.32 at 2011-12-07 09:34:43 -0500
Processing by ListsController#create as JSON
Parameters: {"id"=>0, "title"=>"Made from the iPhone 2!", "list"=>{"id"=>0, "title"=>"Made from the iPhone 2!"}}
WARNING: Can't verify CSRF token authenticity
WARNING: Can't mass-assign protected attributes: id
(0.3ms) BEGIN
SQL (0.9ms) INSERT INTO "lists" ("created_at", "title", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["created_at", Wed, 07 Dec 2011 14:34:43 UTC +00:00], ["title", "Made from the iPhone 2!"], ["updated_at", Wed, 07 Dec 2011 14:34:43 UTC +00:00]]
(16.4ms) COMMIT
Completed 201 Created in 77ms (Views: 1.8ms | ActiveRecord: 21.9ms)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为
inverseMapping
选择器应该足以进行序列化映射编辑:
根据我们的聊天对话,RestKit 产生的警告是由于服务器响应缺少根 KeyPath (返回为裸数组)。为了解决这个问题,我们需要告诉 RestKit 使用特定的映射来映射响应:
I think the
inverseMapping
selector should be enough to make a serialization mappingEdit:
according to our chat conversation, the warnings produced by RestKit were caused by the fact that the server response was lacking the root KeyPath (returned as naked array). To solve the problem we need to tell RestKit to use specific mapping to map the response:
这是来自 RestKit 文档。有一个方便的方法可以设置映射和序列化映射,
这将为您调用 setMapping:forKeyPath: ,然后生成序列化映射并设置根 keyPath 。
This is from the RestKit docs. There is a convenience method that sets both mapping and serialization mapping
This will call setMapping:forKeyPath: for you, then generate a serialization mapping and set the root keyPath as well.