Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 刮取整个API还是严重依赖它?_Ruby On Rails_Ruby_Web Scraping_Api Design - Fatal编程技术网

Ruby on rails 刮取整个API还是严重依赖它?

Ruby on rails 刮取整个API还是严重依赖它?,ruby-on-rails,ruby,web-scraping,api-design,Ruby On Rails,Ruby,Web Scraping,Api Design,我正在rails中建立一个度假村评论网站。目前,一个用户有许多评论,每个评论都属于一个用户 reviews表包含一个expedia\u id字段。所有数据-酒店名称、图像、描述等都是通过对该id的查找从Expedia API中动态提取的。例如,在控制器中点击show操作时,它会使用Expedia\u id向Expedia和my db发出请求,以获取所有评论和内容,并在一页上呈现所有内容。还将请求填充主页(我想是一个带有expedia\u id的Featured表格列) 由于我的整个网站严重依赖A

我正在rails中建立一个度假村评论网站。目前,一个
用户
有许多评论,每个
评论
都属于一个
用户

reviews表包含一个
expedia\u id
字段。所有数据-酒店名称、图像、描述等都是通过对该id的查找从Expedia API中动态提取的。例如,在控制器中点击
show
操作时,它会使用
Expedia\u id
向Expediamy db发出请求,以获取所有评论和内容,并在一页上呈现所有内容。还将请求填充主页(我想是一个带有expedia\u id的
Featured
表格列)


由于我的整个网站严重依赖API,而且我没有一个
Resort
表,再加上由于用户数量巨大,会向Expedia API发出大量请求,因此将结果刮取并写入我的数据库有意义吗,创建记录供以后使用?

中间立场将是最好的解决方案。 创建一个表和模型,在本地存储活动的度假村。在一段时间后使您的本地副本过期(取决于Expedia上度假村更改的频率),并且仅在新的度假村系统上ping api,或者加载已过期的度假村

这将是如何做到这一点的一个基本示例

class Resort < ApplicationRecord #for Rails <=4 do ActiveRecord::Base
  after_find :maybe_update_from_expedia
  ExpirationTime = 1.day #change to fit what is needed

  def self.find_by_expedia_id(expedia_id)
    result = self.where(expedia_id: expedia_id).first
    result || self.create_by_expedia_id(expedia_id)
  end

  def maybe_update_from_expedia
    update_from_expedia if expire_at.nil? || expire_at < Time.now
  end

  private
  def self.create_by_expedia_id(expedia_id)
    record = new(expedia_id: expedia_id)
    record.maybe_update_from_expedia
    record
  end

  def update_from_expedia
    #fetch record from expedia
    #update local data
    self.expire_time = Time.now + ExpirationTime
    self.save
  end
end

class Resortresorts
表,其中包含所需字段和一个
expire\u datetime
。当您试图访问
度假胜地时,您没有,或者
已过期
您向Expedia发出api请求,将结果缓存在数据库中,并更新
expire\u datetime
。@MichaelGorman的评论就是这个问题的答案。@MichaelGorman我同意Josep,您应该将您的评论作为答案发布。除了@MichaelGorman的评论和答案外,您还需要一个定期清理表并确认/更新/清除记录的任务,否则它只会增长并包含陈旧信息
rails runner
将是一个很好的解雇工作的方法。@theTinMan是的,这将是一个很好的优化,就像任何
度假胜地的
过期日期>1.month
(至少一个月未被触摸)将
删除
(注意这需要删除而不是销毁,因为销毁会初始化记录并尝试更新)我们没有使用
find\u或\u create\u by(expedia\u id:expedia\u id)的任何原因
。看起来你在复制很多现成的
rails
code我记得在
find\u或\u create\u by
初始化后不启动
回调时出现了问题,但这可能是在较旧的rails环境中,我发现我在大多数时候都做得很好。它使模型保持较薄,但在r回忆一下,作为一个正式的回答,我认为这里的透明度更有意义。好吧,Donethanks,如果我们能够确定
find\u或\u create\u by
find\u或\u initialize\u by
在初始化后回拨会命中
,它会使代码更干净。一项小研究表明,它应该总是命中回调,所以我添加了t他浓缩了这个版本,用完整的版本来解释发生了什么
class Resort < ApplicationRecord #for Rails <=4 do ActiveRecord::Base
  after_initialize :maybe_update_from_expedia
  ExpirationTime = 1.day #change to fit what is needed

  private

  def maybe_update_from_expedia
    update_from_expedia if expire_at.nil? || expire_at < Time.now
  end

  def update_from_expedia
    #fetch record from expedia
    #update local data
    self.expire_time = Time.now + ExpirationTime
    self.save
  end
end