Tintin81
Tintin81

Reputation: 10207

How to have instance variable redefined if database value changes?

In my Rails 4 app I have this module which retrieves a bunch of geo data about a user based on his/her IP address:

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

Since I don't want to hit the api.hostip.info service too many times, I thought it's a good idea to store its JSON response in an instance variable.

This works.

But if the user's IP address (which is stored in the database) changes, my function still shows the data based on the old IP address.

Is there a way to redefine the instance variable @response if the user's IP address database field changes?

Thanks for any help.

Upvotes: 0

Views: 65

Answers (2)

ptd
ptd

Reputation: 3053

You have two main options.

The first is to create a new method that you call if you notice that the ip address changed:

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

The better option, I think, would be to use caching to store the response, instead of an instance variable. You could then use the ip address as part of the cache.

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

This way, you will always be storing the location information for that particular ip address and the cache and will automatically cache the new response when the ip changes.

Upvotes: 1

SteveTurczyn
SteveTurczyn

Reputation: 36860

You could store the responses in a hash and just return the appropriate hash entry...

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

Upvotes: 3

Related Questions