Как я могу вернуть определенные ключи / значения json из API после поиска, используя гем HTTParty? - PullRequest
0 голосов
/ 24 апреля 2019

На данный момент у меня есть простое приложение, которое использует внешний API и позволяет пользователю запрашивать и возвращать json. Он возвращает все ключи / значения, но мне бы хотелось, чтобы он возвращал lat и lon в формате json, или, по крайней мере, я хотел бы только показать эти два в моем представлении. Вот мой код:

locationiq_api.rb

class LocationiqApi
  include HTTParty

  BASE_URI = "https://eu1.locationiq.com/v1/search.php"

  attr_accessor :city

  def initialize(api_key, format = "json")
    @options = { key: api_key, format: format }
  end

  def find_coordinates(city)
    self.class.get(BASE_URI, query: @options.merge({ q: city }))
  end

  def handle_error
    if find_coordinates.code.to_i = 200
      find_coordinates.parsed_response
    else
      raise "Couldn't connect to LocationIQ Api"
    end
  end
end 

locations_controller.rb

class LocationsController < ApplicationController

  def index
    @search = LocationiqApi.new("pk.29313e52bff0240b650bb0573332121e").find_coordinates(params[:q])
  end
end

locations.html.erb

<main>
  <h1>Location Search</h1>
  <!-- Button to search find coordinates -->
  <%= form_tag(locations_path, method: :get) do %>
    <%= label_tag(:q, "Search: ") %>
    <%= text_field_tag(:q) %>
    <%= submit_tag("Find coordinates") %>
  <% end %><br>

  <h2>Search results:</h2>

</main>

<%= @search %>

Возвращенный JSON:

[{"place_id":"100066","licence":"https:\/\/locationiq.com\/attribution","osm_type":"node","osm_id":"107775","boundingbox":["51.3473219","51.6673219","-0.2876474","0.0323526"],"lat":"51.5073219","lon":"-0.1276474","display_name":"London, Greater London, England, SW1A 2DX, United Kingdom","class":"place","type":"city","importance":0.9654895765402,"icon":"https:\/\/locationiq.org\/static\/images\/mapicons\/poi_place_city.p.20.png"}]

Ответы [ 2 ]

1 голос
/ 24 апреля 2019

Предположим, у вас есть строка JSON, которая выглядит, например, следующим образом:

"[{\"place_id\":\"100066\",\"lat\":\"51.5073219\",\"lon\":\"-0.1276474\",\"class\":\"place\",\"type\":\"city\"}]"

Тогда вы сможете сделать (грубо говоря):

JSON.dump(
  JSON.
    parse(
      "[{\"place_id\":\"100066\",\"lat\":\"51.5073219\",\"lon\":\"-0.1276474\",\"class\":\"place\",\"type\":\"city\"}]"
    ).
    first.
    slice('lat', 'lon')
)

Это должно дать вам:

 => "{\"lat\":\"51.5073219\",\"lon\":\"-0.1276474\"}" 

Теперь я напомню, что HTTParty может уже преобразовать ответ API в объект Ruby (массив или хэш), так что JSON.dump может не понадобиться.И, возможно, вам понадобятся другие скрипты (например, вы можете использовать with_indifferent_access, если вы предпочитаете работать с символами в качестве ключей вместо строк).

Просто чтобы было понятно, если вы хотите, чтобы этобыть частью вашего метода класса, тогда вы можете сделать что-то вроде:

class LocationiqApi
  include HTTParty

  BASE_URI = "https://eu1.locationiq.com/v1/search.php"

  attr_accessor :city

  def initialize(api_key, format = "json")
    @options = { key: api_key, format: format }
  end

  def find_coordinates(city)
    JSON.dump(
      JSON.
        parse(
          self.class.get(BASE_URI, query: @options.merge({ q: city }))
        ).
        first.
        slice('lat', 'lon')
    )
  end

  def handle_error
    if find_coordinates.code.to_i = 200
      find_coordinates.parsed_response
    else
      raise "Couldn't connect to LocationIQ Api"
    end
  end
end

Если self.class.get(BASE_URI, query: @options.merge({ q: city })) возвращает что-либо кроме допустимой строки JSON, которая представляет array из hashes, то этовероятно потерпит неудачу.

Я полагаю, что ключевые биты:

  • Вам необходимо преобразовать (проанализировать) ваш JSON во что-то, с чем может работать Ruby;
  • После анализа вам нужнополучить hash из ваших array хешей (при условии, что массив хешей всегда является результатом синтаксического анализа);
  • Вы можете использовать slice, чтобы использовать только те пары ключ-значение, которые вы хотите;
  • Затем, поскольку вы указали, что хотите вернуть JSON, вам необходимо превратить ваш объект Ruby обратно в JSON, используя, например, JSON.dump.Вы также можете использовать, я полагаю, to_json.В зависимости от того, что плывет на вашей лодке.
0 голосов
/ 24 апреля 2019

Попробуйте это:

@search.map {|r| {lat: r['lat'], lon: r['lon']} }

Будет массивом хэшей

...