Rails 3.1.3 REST: невозможно извлечь ошибки со стороны активного ресурса (сериализатор json) - PullRequest
2 голосов
/ 28 декабря 2011

У меня есть Сервер, работающий с активными моделями (не активной записью), и клиентская сторона с активным ресурсом.

Например, контроллер на стороне сервера имеет такой код

...
      def update

        if @supplier.update_attributes(params[:supplier])
           respond_to do |format|
              format.any  { head :ok }
            end
        else

          respond_with(@supplier.errors,:status => :unprocessable_entity)
        end    
      end
...

Активная модель имеет следующий код

...
     class Subscriber < BaseModel
     include ActiveModel::Validations  
     include ActiveModel::Serialization  
     include ActiveModel::Callbacks  
     extend ActiveModel::Naming
     validates :email,  :format =>   /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i  
     def update_attributes(attributes={})
         self.attributes.merge!(attributes)
         self.save
      end   

      def save
          if self.valid?
            super
          else
            false
          end    
      end   
... 

Я набираю следующий код с консоли rails клиентского приложения

 s = Supplier.find(13)
 s.email = ''
 s.save

вернуть false из-за неверного адреса электронной почты

это объект ошибок с сервера перед отправкой с response_with

#<ActiveModel::Errors:0x000001012e9d78 @base=#<Supplier:0x000001032bf8c8 @attributes={:id=>13, :company_name=>.......}, @validation_context=nil, @errors=#<ActiveModel::Errors:0x000001012e9d78 ...>>, @messages={:email=>["is invalid"]}>

и клиент имеет следующие значения s

   .... @remote_errors=#<ActiveResource::ResourceInvalid: Failed.  Response code = 422.  Response message = .>, @validation_context=nil, @errors=#<ActiveResource::Errors:0x000001034991d0 @base=#<Didww::Supplier:0x000001034af048 ...>, @messages={}>> 

Почему я не могу принять ошибки на стороне клиента (сообщения - пустой хеш)?

UPD: клиент получает {} в теле ответа

"--- !ruby/object:Net::HTTPClientError \nbody: \"{}\"\nbody_exist: true\ncode: \"422\"\nheader: \n  content-type: \n  - application/json; charset=utf-8\n  x-ua-compatible: \n  - IE=Edge\n  cache-control: \n  - no-cache\n  x-runtime: \n  - \"0.128106\"\n  content-length: \n  - \"2\"\n  server: \n  - WEBrick/1.3.1 (Ruby/1.9.2/2011-02-18)\n  date: \n  - Thu, 29 Dec 2011 10:57:50 GMT\n  connection: \n  - close\n  set-cookie: \n  - _api_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRkkiJTM5OWQwNTZhMzI1MzcxYzdjZGI2NzNkZWZjNWE0OTQwBjsAVA%3D%3D--b9a0f65001dd994f269800f1c56259523ab669b1; path=/; HttpOnly\nhttp_version: \"1.1\"\nmessage: \"\"\nread: true\nsocket: \n"

UPD2 если действие контроллера выглядит следующим образом

 @supplier.update_attributes(params[:supplier])
 respond_with(@supplier)

чем ответ выглядит следующим

"--- !ruby/object:Net::HTTPClientError \nbody: \"{\\\"email\\\":[\\\"is invalid\\\"]}\"\nbody_exist: true\ncode: \"422\"\nheader: \n...

так что я думаю проблема в том, что клиент и сервер используют разные логики для сериализации

  class Errors < ActiveModel::Errors

   # Grabs errors from a json response.
    def from_json(json, save_cache = false)
      array = Array.wrap(ActiveSupport::JSON.decode(json)['errors']) rescue []
      from_array array, save_cache
    end

клиент ожидает, что сервер использует ключ ошибок для хэша ошибок ({: errors => {: email => ["invalid"]}}), но сервер этого не делает (просто {: email => ["недопустим «]})

Что мне не хватает ???

1 Ответ

1 голос
/ 29 декабря 2011

Так что я сам нашел проблему.Это ошибка контроллера rails 3.1. Он исправлен в rails 3.2.0.rc1

pull pull https://github.com/rails/rails/pull/3272/files

https://github.com/rails/rails/pull/3046/files

...