ruby-on-rails - Rails 使用 API

标签 ruby-on-rails ruby httparty

我是使用 API 的初学者。我正在尝试与 Forecast API 合作。我不想使用它的 official wrapper ,因为首先我喜欢学习和学习。

class Forecast
  include HTTParty

  base_uri "api.forecast.io/forecast/#{@api_key}/#{@latitude},#{@longitude}"

  def initialize(api_key,latitude,longitude)
     self.api_key = api_key
     self.latitude = latitude
     self.longitude = longitude
  end


end

现在初始化后下一步应该是什么。我尝试使用 httparty gem 示例来理解,但无法弄清楚到底要做什么。

您能帮我修复它并使用 API 指向相关资源吗?

最佳答案

在使用 API 时,我不使用 httparty gem,而是使用 typhoeus gem它允许发出并行 http 请求,从而实现并发,但我相信如果您使用 httparty,下面的示例也将起作用。 我将使用一个简单的示例来展示我如何使用 API。假设您正在尝试与 JSON API 服务通信以获取产品列表。

服务端点的 URL 为 http://path/to/products.json

在您的应用程序中,您可以拥有一个带有 index 操作的 products_controller.rb,如下所示:

class ProductsController < ApplicationController
  def index
   # make a http request to the api to fetch the products in json format
    hydra = Typhoeus::Hydra.hydra
    get_products = Typhoeus::Request.new('http://path/to/products.json')
    get_products.on_complete do |response|
      products = MultipleProducts.from_json(response.body)
      @products = products.products
    end
    hydra.queue get_products
    hydra.run
  end
end

假设对 http://path/to/products.json 的 http 请求返回以下 json

{"products" [{"id": 1,
  "name": "First product",
  "description": "Description",
  "price": "25.99"}, {"id": 2,
  "name": "Second product",
  "description": "Description",
  "price": "5.99"}]

这个 json 可以包装在一个名称类似于 multiple_products.rb 的类中,如下所示:

class MultipleProducts
  attr_reader :products 
  def initialize(attributes)
    @products = attributes[:products]
  end
  def self.from_json(json_string)
    parsed = JSON.parse(json_string)
    products = parsed['products'].map do |product|
      Product.new(product)
    end
    new(products: products)
  end
end

然后您可以使用 ActiveModel创建这样的产品模型:

class Product
  include ActiveModel::Serializers::JSON
  include ActiveModel::Validations
  ATTRIBUTES =  [:id, :name, :description, :price]
  attr_accessor *ATTRIBUTES
  validates_presence_of :id, :name, :price

  def initialize(attributes = {})
    self.attributes = attributes
  end

  def attributes
    ATTRIBUTES.inject(ActiveSupport::HashWithIndifferentAccess.new) do |result, key|
      result[key] = read_attribute_for_validation(key)
      result
    end
  end

 def attributes= (attrs)
   attrs.each_pair {|k, v| send("#{k}=", v)}
 end

 def read_attribute_for_validation(key)
   send(key)
 end
end

在您的 app/views/products/index.html 中,您可以:

<h1>Products Listing</h1>
 <ul>
   <% @products.each do |product| %>
     <li>Name: <%= product.name %> Price: <%= product.price %> </li>
   <% end %>
 </ul>

这将列出从 api 获取的所有产品。 这只是一个简单的示例,使用 API 时还涉及更多内容。我建议您阅读Service-Oriented Design with Ruby and Rails了解更多详情。

关于ruby-on-rails - Rails 使用 API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24304831/

相关文章:

ruby-on-rails - heroku Errno::ENOENT(没有这样的文件或目录 -/assets/)

python - 如何将 Ruby 模块移植到 Python

ruby-on-rails - include有反义词吗? Ruby 中的方法?

ruby - 如何使用 HTTParty 实现此 POST 请求?

ruby-on-rails - rails : Prevent parent model from being created and surfacing child model validation errors

ruby-on-rails - 如何正确使用对同一模型有多个关联的工厂?

ruby - 用于抓取城市、州、 zip 的正则表达式

ruby - 使用 HTTParty 时的 URI::InvalidURIError

ruby - HTTPS 和 HTTParty - 超时和 EOF

ruby-on-rails - Rails迁移不适用于清空功能