如何使用HTTParty gem在搜索后从API返回特定的json键/值?

问题描述 投票:-1回答:2

目前我有一个简单的应用程序,它使用外部API并允许用户查询并返回json。它返回所有键/值,但我只想在json中返回latlon,或者至少我只想在我的视图中显示这两个。这是我的代码:

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"}]
ruby-on-rails ruby geocoding rails-api httparty
2个回答
1
投票

假设您有一个类似于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 }))返回除了代表JSONarray的有效hashes字符串之外的任何内容,那么这可能会失败。

我想关键位是:

  • 您需要将JSON转换(解析)为Ruby可以使用的东西;
  • 解析之后,你需要从你的hash中获取一个array(假设一个哈希数组总是解析的结果);
  • 您可以使用slice仅使用您想要的键值对;
  • 然后,由于您规定要返回JSON,因此需要使用例如JSON.dump将Ruby对象转换回JSON。你也可以使用to_json。无论哪个漂浮你的船。

-1
投票

试试这个:

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

将是一系列哈希

© www.soinside.com 2019 - 2024. All rights reserved.