从iOS客户端返回状态422修复到Rails应用程序

时间:2014-01-23 08:44:07

标签: ios ruby-on-rails http afnetworking http-status-codes

我有一个带有Business模型对象的Rails应用,其计数为visits。我有一个使用AFNetworking 2.0与这个Rails应用程序交互的iOS客户端,当用户在应用程序中点击一个业务时,它会向Rails应用程序发送一个PATCH,为该业务增加visits。但是,我从服务器返回状态代码422“Unprocessable Entity”错误,并且服务器上的业务visits计数没有增加。

AFHTTPSessionManager - iOS

- (NSURLSessionDataTask *)visitVenue:(NOTVenue *)venue withCompletionBlock:(void (^)(BOOL success))completionBlock {
NSURLSessionDataTask *dataTask = [self PATCH:[NSString stringWithFormat:@"businesses/%li.json", (long)[venue.identifier integerValue]]
                                  parameters:@{@"visits": @(venue.numberOfVisits + 1)}
                                     success:^(NSURLSessionDataTask *task, id responseObject) {
                                         NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)task.response;

                                         if (httpResponse.statusCode == 200) {
                                             dispatch_async(dispatch_get_main_queue(), ^{
                                                 completionBlock(YES);
                                             });
                                         } else {
                                             dispatch_async(dispatch_get_main_queue(), ^{
                                                 completionBlock(NO);
                                             });
                                         }
                                     }
                                     failure:^(NSURLSessionDataTask *task, NSError *error) {
                                         dispatch_async(dispatch_get_main_queue(), ^{
                                             completionBlock(NO);
                                         });
                                     }];

return dataTask;

}

企业控制器 - Rails

# PATCH/PUT /businesses/1
# PATCH/PUT /businesses/1.json
def update
  respond_to do |format|
    if @business.update(business_params)
      format.html { redirect_to @business, notice: 'Business was successfully updated.' }
      format.json { head :no_content }
    else
      format.html { render action: 'edit' }
      format.json { render json: @business.errors, status: :unprocessable_entity }
    end
  end
end

2 个答案:

答案 0 :(得分:0)

如果Web API允许递增模型对象的计数器,它应该有一个专用的“方法”。

通常,如果客户端本身增加在从服务器接收的本地副本上执行的计数器然后尝试,则增量计数器功能将无法正常工作通过编写PATCH请求来更新服务器的值,其中客户端仅发送值local_counter+1。与此同时,其他客户端可能有相同的想法,在这种情况下,服务器上的计数器值将变得腐败。此外,可以将服务器上的计数器更新为任何值 - 这当然是不可取的。

结果是,计数器变量必须只读为客户端。

必须有其他方法(由Web API定义),客户端可以在其中完成此操作。例如,REST API将定义客户端可以创建的特定“资源”(例如某种“票证”或“预订”)。此资源的 creation 将增加服务器上的计数器变量。

修改

如果您正在测试Web API,则命令行工具curl非常宝贵:

测试PATCH请求:

在Terminal.app中输入以下命令:

curl -sSv -X PATCH \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -d '{"email”:”jappleseed@mail.com"}' \
    http://localhost:3000/api/v1/users/123 \
    | python -m json.tool

答案 1 :(得分:0)

Rails API site找到了正确的解决方案。这是代码:

class ApplicationController < ActionController::Base
  protect_from_forgery
  skip_before_action :verify_authenticity_token, if: :json_request?

  protected

  def json_request?
    request.format.json?
  end
end