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

How to have instance variable redefined if database value changes?

在我的 Rails 4 应用程序中,我有这个模块,它根据 his/her 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

感谢您的帮助。

您可以将响应存储在散列中,并且 return 适当的散列条目...

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

您有两个主要选择。

首先是创建一个新方法,如果您注意到 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 更改时自动缓存新响应。