如果数据库值发生变化,如何重新定义实例变量?

时间:2015-01-09 16:32:44

标签: ruby-on-rails ruby

在我的Rails 4应用程序中,我有这个模块,它根据用户的IP地址检索一堆关于用户的地理数据:

module GeoLocation

  def self.get(key, ip_address)
    response_hash = JSON.parse(response(ip_address))
    response_hash[key]
  end

  private

  def self.response(ip_address)
    @response ||= RestClient.get("http://api.hostip.info/get_json.php?ip=#{ip_address}&position=true")
  end

end

由于我不想太多次点击api.hostip.info服务,我认为将JSON响应存储在实例变量中是一个好主意。

这很有效。

但是如果用户的IP地址(存储在数据库中)发生了变化,我的功能仍然会根据旧的IP地址显示数据。

如果用户的IP地址数据库字段发生变化,有没有办法重新定义实例变量@response

感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

您可以将响应存储在哈希中,只返回相应的哈希条目...

def self.response(ip_address)
    @response ||= {}
    @response[ip_address] ||= RestClient.get("http://api.hostip.info/get_json.php?ip=#{ip_address}&position=true")
  end

答案 1 :(得分:1)

您有两个主要选择。

第一种是创建一个新方法,如果您注意到IP地址已更改,则调用该方法:

def self.new_response(ip_address)
  @response = RestClient.get("http://api.hostip.info/get_json.php?ip=#{ip_address}&position=true")
end

我认为更好的选择是使用缓存来存储响应,而不是实例变量。然后,您可以使用IP地址作为缓存的一部分。

def self.response(ip_address)
  Rails.cache.fetch("api-response-#{ip_address}") do
    RestClient.get("http://api.hostip.info/get_json.php?ip=#{ip_address}&position=true")
  end
end

这样,您将始终存储该特定IP地址和缓存的位置信息,并在IP更改时自动缓存新响应。