Как сгладить ответ JSON при использовании ActiveResource?

У меня есть API и клиентское приложение, и я использую рельсы с ActiveResource.

У меня есть модель Recruiter, которая наследуется от ActiveResource::Base

Скажем, на стороне клиента я пишу:

dave = Recruiter.new(email: "[email protected]", password: "tyu678$--è", full_name:      "David Blaine", company: "GE") 
dave.save

Запрос, который я отправляю, имеет следующий формат:

{"recruiter":{
    "email": "[email protected]",
    "password": "tyu678$--è",
    "full_name": "David Blaine",
    "company": "GE"
    }
}

и ответ Json, который я получаю от API, отформатирован следующим образом:

   {"recruiter":{
    "email": "[email protected]",
    "password": "tyu678$--è",
    "full_name": "David Blaine",
    "company": "GE",
    "foo": "bar"
    },
    "app_token":"ApfXy8YYVtsipFLvJXQ"
}

Проблема в том, что это позволит мне получить доступ к токену приложения с помощью dave.app_token, но я не могу, например, написать dave.foo, что вызывает ошибку.

Есть ли способ сгладить ответ или прочитать его рекурсивно, чтобы я мог получить доступ ко всем атрибутам моего экземпляра, сохраняя при этом формат ответа API?


person user3778624    schedule 10.07.2014    source источник


Ответы (1)


Просматривая весь процесс ActiveResource, вы можете перезаписать метод load в своей модели Recruiter.

Я только что добавил код в раздел #HACK, который "выравнивает" ваши атрибуты.

def load(attributes, remove_root = false, persisted = false)
  raise ArgumentError, "expected an attributes Hash, got #{attributes.inspect}" unless attributes.is_a?(Hash)
  @prefix_options, attributes = split_options(attributes)

  # HACK
  if !attributes[:app_token].nil?
    attributes[:recruiter]["app_token"] = attributes[:app_token]
    attributes = attributes[:recruiter]
  end
  # /HACK

  if attributes.keys.size == 1
    remove_root = self.class.element_name == attributes.keys.first.to_s
  end

  attributes = ActiveResource::Formats.remove_root(attributes) if remove_root

  attributes.each do |key, value|
    @attributes[key.to_s] =
    case value
    when Array
      resource = nil
      value.map do |attrs|
        if attrs.is_a?(Hash)
          resource ||= find_or_create_resource_for_collection(key)
          resource.new(attrs, persisted)
        else
          attrs.duplicable? ? attrs.dup : attrs
        end
      end
    when Hash
      resource = find_or_create_resource_for(key)
      resource.new(value, persisted)
    else
      value.duplicable? ? value.dup : value
    end
  end
  self
end
person Jérôme Boé    schedule 10.07.2014