在我的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
?
感谢您的帮助。
答案 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更改时自动缓存新响应。