Rails RestKit POST 请求 json 的根类丢失

Posted

技术标签:

【中文标题】Rails RestKit POST 请求 json 的根类丢失【英文标题】:Rails RestKit POST request json's root class missing 【发布时间】:2012-01-13 19:33:43 【问题描述】:

我以前遇到过这个问题,我已经解决了,但我知道解决方法没有以正确的方式完成。有人可以为我指出正确的方向吗?

基本上我通过RESTkitpostObjectios sim 创建了一个对象,我收到了这条消息:

Processing PeopleController#create (for 127.0.0.1 at 2012-01-13 03:55:46) [POST]
  Parameters: "name"=>"data"

Person Create (0.4ms)   INSERT INTO "people" ("created_at", "updated_at", "name")
VALUES('2012-01-13 11:55:46', '2012-01-13 11:55:46', NULL)
Completed in 27ms (View: 1, DB: 0) | 200 OK 

一位好先生指出,我的 create 函数中的类只接受一个我忽略的 :person 类。

def create
@person = Person.new(params[:person]) , thus looking for "person" => "name"=>"data"

我通过这样做解决了这个问题

@person =Person.new(name:=>params[:name]) 因为我只发送"name"=>"data" 现在它创建好了,我可以在我的 ios sim 上看到该条目。但我知道这不是正确的方法。正确的方法应该是"person" => "name"=>"data" 发送到原始函数。另外,我得到一个错误,找不到 keyPath 的对象映射:“。有什么想法吗?

这是我的 xcode:

@interface Data: NSObject// imaginary over arching class
   Person * person;
   NSArray *dog;
@property (nonatomic, retain) Person * person;
@property (nonatomic, retain) NSArray * dog;

@interface Data : NSObject 
Person *person;
NSArray *dogs;

@property (nonatomic ,retain) Person *person;
@property (nonatomic ,retain) NSArray *dogs;
@end

@interface Person : NSObject 

NSString *name;
NSNumber *personId;
NSDate   *updatedAt;
NSDate   *createdAt;



@property (nonatomic , retain) NSDate * createdAt;
@property (nonatomic , retain) NSDate * updatedAt;
@property (nonatomic , retain) NSNumber  *personId;
@property (nonatomic , retain) NSString *name;
@end

RKObjectMapping* userMapping = [RKObjectMapping mappingForClass:[Person class]];

[userMapping mapKeyPath:@"created_at" toAttribute:@"createdAt"];
[userMapping mapKeyPath:@"updated_at" toAttribute:@"updatedAt"];
[userMapping mapKeyPath:@"name" toAttribute:@"name"]; 
[userMapping mapKeyPath:@"id" toAttribute:@"personId"];

RKObjectMapping* dogMapping = [RKObjectMapping mappingForClass:[Dog class]];
[dogMapping mapKeyPath:@"created_at" toAttribute:@"createdAt"]; 
[dogMapping mapKeyPath:@"person_id" toAttribute:@"spersonId"]; 
[dogMapping mapKeyPath:@"name" toAttribute:@"name"]; 
[dogMapping mapKeyPath:@"updated_at" toAttribute:@"updatedAt"]; 
[dogMapping mapKeyPath:@"id" toAttribute:@"dogId"]; 

RKObjectMapping *dataMapping = [RKObjectMapping mappingForClass:[Data class]]; 
[dataMapping mapKeyPath:@"dog" toAttribute:@"dogs"]; 
[dataMapping mapKeyPath:@"person" toRelationship:@"person" withMapping:userMapping]; 
[[RKObjectManager sharedManager].mappingProvider addObjectMapping:dataMapping]; 

[[RKObjectManager sharedManager] loadObjectsAtResourcePath:@"/people"       
objectMapping:dataMapping delegate:self]; 

RKObjectRouter * router = [RKObjectManager sharedManager].router;
[router routeClass: [Person class] toResourcePath:@"/people/:personId"];
[router routeClass: [Person class] toResourcePath:@"/people"          
forMethod:RKRequestMethodPOST];

RKObjectMapping *personSerializationMapping = [RKObjectMapping mappingForClass:
[NSMutableDictionary class]];
[personSerializationMapping attribute:@"name", nil];
[RKObjectManager sharedManager].mappingProvider 
setSerializationMapping:personalSerializationMapping forClass: [Person class]];

Person *dave = [[Person alloc]init];
dave.name = @"Dave";
[[RKObjectManager sharedManager] postObject:dave delegate:self];

【问题讨论】:

感谢 @favo 编辑我的鸡抓痕 =] 【参考方案1】:

Person为例:

RKObjectMapping* userMapping = [RKObjectMapping mappingForClass:[Person class]];

[userMapping mapKeyPath:@"created_at" toAttribute:@"createdAt"];
[userMapping mapKeyPath:@"updated_at" toAttribute:@"updatedAt"];
[userMapping mapKeyPath:@"name" toAttribute:@"name"]; 
[userMapping mapKeyPath:@"id" toAttribute:@"personId"];

要使用根路径配置 RestKitPOST,请替换:

[[[RKObjectManager sharedManager] mappingProvider] 
         setSerializationMapping:personalSerializationMapping 
                        forClass:[Person class]];

与:

[[[RKObjectManager sharedManager] mappingProvider]
                 registerMapping:objectMapping 
                 withRootKeyPath:@"person"];

现在 Rails 将收到 "person" => "name"=>"data" 而不是 "name"=>"data"

供参考,这里是registerMapping魔法

- (void)registerObjectMapping:(RKObjectMapping *)objectMapping withRootKeyPath:(NSString *)keyPath 
    // TODO: Should generate logs
    objectMapping.rootKeyPath = keyPath;
    [self setMapping:objectMapping forKeyPath:keyPath];
    RKObjectMapping* inverseMapping = [objectMapping inverseMapping];
    inverseMapping.rootKeyPath = keyPath;
    [self setSerializationMapping:inverseMapping forClass:objectMapping.objectClass];

setMappingsetSerializationMapping 都使用巧妙的 [objectMapping inverseMapping] 技巧。

【讨论】:

【参考方案2】:

是的,终于明白了。映射错误。而不是addObjectMapping: dataMapping,它应该是userMappingkeyPath人,即userMapping。 btw thnx @favo 用于编辑我的鸡肉刮痕 =] 现在它可以 GETPOST 很好!

【讨论】:

它实际上仍然无法正常工作我忘记了我在 Rails 中为 def create 破解了源代码以获取名称而不是人,但这破坏了服务器的网页......所以它仍然没有t 工作 =/【参考方案3】:

为了完成主义者,关于“找不到关键路径的映射''”的错误似乎是 Rails 创建操作的问题。

在这个 SO 问题中有一个很好的答案:how to post an object to Rails using RESTKit

【讨论】:

以上是关于Rails RestKit POST 请求 json 的根类丢失的主要内容,如果未能解决你的问题,请参考以下文章

使用 RestKit 在 post 请求中寻求帮助

使用 RestKit 以 XML 格式发送 post 请求

使用 RestKit 发出 POST 请求

RestKit POST 对象到服务器,但服务器收到空的 GET 请求

POST 中的 Restkit url 映射

postObject 的 Restkit 返回值