【问题标题】:Rails how to save data upon creation with an external API?Rails 如何在使用外部 API 创建时保存数据?
【发布时间】:2020-07-11 03:13:07
【问题描述】:

在我的bike_rental_shops 应用程序中,我让这些商店能够管理他们的自行车租赁。

上下文 自行车租赁公司也在外部网站上提供自行车,因此我将我的 Rails 应用程序与这些外部网站连接起来。当用户转到索引页面时,我目前正在我的控制器中处理此问题。在加载索引页面之前,API 调用外部租赁网站,新的自行车租赁应保存在数据库中。

问题 如何只保存新的租金而不是链接到某个外部租赁网站的所有租金?

当前考虑 我唯一能想到的就是为特定的外部网站添加一个带有{external_website}_rental_id 的数据库列,这样我就可以匹配它们。但是,这意味着我需要为每个外部租赁网站添加一个单独的 rent_id。

代码

rentals_controller.rb


def index
  shop = Shop.find(params[:id])
  request_rental_api
  @bikes = shop.bikes
end

private
def request_rental_api
    # set variables
    base_url = "https://www.rentalwebsite.com"
    url = "/rest/api/rentals"
    token = 'TOKEN'


    # init connection object
    connection = Faraday.new(:url => base_url) do |c|
       c.use Faraday::Request::UrlEncoded
       c.use Faraday::Response::Logger
       c.use FaradayMiddleware::FollowRedirects
       c.adapter Faraday::Adapter::NetHttp
    end

    # send request
    response = connection.get url do |request|
      request.headers["Authorization"] = token
      request.headers["Accept"] = "application/json"
    end
    bookings = JSON.parse(response.body['results'])

    # check if rental is unique, and if so save it.
    # Rental.create(????)
  end

JSON 输出 API

{
  "next": null,
  "previous": null,
  "results": [
    {
      "activation_requested": false,
      "id": 21664,
      "slug": "rental-test"
      #more information....
   }
}]

【问题讨论】:

    标签: ruby-on-rails api-design faraday


    【解决方案1】:

    您可以创建 2 列

    provider_rental_id id 在响应 JSON 中返回

    provider 请求的提供者名称

    然后只创建新记录

    rental_ids = bookings['results'].map { |r| r['id'] }
    return if rental_ids.none?
    
    existing_rental_ids = Rental.where(provider_rental_id: rental_ids, provider: 'Name of Provider').pluck(:provider_rental_id)
    new_rental_ids = rental_ids - existing_rental_ids
    
    new_rental_ids.each do |rental_id|
      Rental.create(
        provider: 'Name of Provider',
        provider_rental_id: rental_id, 
        ...
    

    或者如果您使用的是 rails 6,您可以查看upsert_all
    注意:它不会实例化任何模型,也不会触发 Active Record 回调或验证。

    另外尝试将其移动到后台 cronjob 中

    【讨论】:

    • 感谢@PGill,也感谢您对 cronjob 的评论。真的很有帮助。
    猜你喜欢
    • 1970-01-01
    • 2019-06-18
    • 2012-12-31
    • 1970-01-01
    • 2015-12-07
    • 2020-02-06
    • 1970-01-01
    • 1970-01-01
    • 2014-02-03
    相关资源
    最近更新 更多