Frage Aktive Ressource, die sich darüber beschweren, erwartet einen Hash


Ich verwende aktive Ressource, um Daten von einer API zu erhalten und anzuzeigen,
Mein Controller model.rb hat

class Thr::Vol::Dom < ActiveResource::Base
  class << self
    def element_path(id, prefix_options = {}, query_options = nil)
      prefix_options, query_options = split_options(prefix_options) if query_options.nil?
      "#{prefix(prefix_options)}#{collection_name}/#{id}#{query_string(query_options)}"
    end

    def collection_path(prefix_options = {}, query_options = nil)
      prefix_options, query_options = split_options(prefix_options) if query_options.nil?
      "#{prefix(prefix_options)}#{collection_name}#{query_string(query_options)}"
    end
  end

  ActiveResource::Base.site = 'http://10.00.0.00:8888/'

  self.format = :json
  self.collection_name= "/vv/test/domains"

  def self.find
    x = superclass.find(:one, :from => '/vv/test/domains/2013-06-25T05:03Z')
    x
  end
end

Wenn ich diese Thr :: Vol :: Dom.find-Methode aufrufen, wird der folgende Fehler zurückgegeben:

ArgumentError: expected an attributes Hash, 
  got ["0.0.0.0", "1.1.1.1", "2.2.2.2", "3.3.3.3", "4.4.4.4"]

Von der API wird erwartet, dass sie so etwas füttert

{"abs.com":["0.0.0.0", "1.1.1.1", "2.2.2.2", "3.3.3.3", "4.4.4.4"]}

für den Anruf habe ich gemacht.

Die API gibt den korrekten Hash zurück, aber ich nehme an, die aktive Ressource kann sie nicht richtig lesen, sie liest direkt den Wert im Schlüssel-Wert-Paar des Hash.

Ich möchte diesen "ArgumentError" -Fehler beheben, ich möchte den Inhalt des zurückgegebenen Hash in der Ansicht anzeigen.


5
2018-06-29 00:11


Ursprung


Antworten:


Sie können ändern, wie ActiveResource die json-Antwort behandelt

class YourModel < ActiveResource::Base
  self.format = ::JsonFormatter.new(:collection_name)
end

Im lib/json_formatter.rb

class JsonFormatter
  include ActiveResource::Formats::JsonFormat

  attr_reader :collection_name

  def initialize(collection_name)
    @collection_name = collection_name.to_s
  end

  def decode(json)
    remove_root(ActiveSupport::JSON.decode(json))
  end

  private

  def remove_root(data)
    if data.is_a?(Hash) && data[collection_name]
      data[collection_name]
    else
      data
    end
  end
end

Wenn du passierst self.format = ::JsonFormatter.new(:categories) es wird finden und entfernen categories Root-Element in Ihrem JSON zurückgegeben von Ihrer API.


16
2018-06-29 11:19



Die API gibt ein JSON-Objekt und keinen Ruby-Hash zurück. Sie müssen es in einen Hash konvertieren, indem Sie das JSON-Modul von Ruby verwenden:

require 'JSON'

hash = JSON.parse('{"abs.com":["0.0.0.0", "1.1.1.1", "2.2.2.2", "3.3.3.3", "4.4.4.4"]}')

Dies wird einen Hash zurückgeben und dann werden Sie feststellen, dass das Schlüssel / Wert-Paar wie erwartet funktioniert:

hash["abs.com"] => ["0.0.0.0", "1.1.1.1", "2.2.2.2", "3.3.3.3", "4.4.4.4"]

0
2018-06-29 10:22