Question

In my Rails application I have built a little gravatar helper that checks if a user has a gravatar or not. If the user has one, it will be displayed. If s/he hasn't, a generic placeholder image will be displayed instead.

module GravatarHelper

  def gravatar
    if signed_in? && gravatar?(current_user)
      id = Digest::MD5::hexdigest(current_user.email.strip.downcase)
      url = 'http://www.gravatar.com/avatar/' + id + '.jpg'
      image_tag(url)
    else
      image_tag("placeholder.png")  
    end
  end

  private

  def gravatar?(user)
    hash = Digest::MD5.hexdigest(user.email.to_s.downcase)
    options = { :rating => 'x', :timeout => 2 }
    http = Net::HTTP.new('www.gravatar.com', 80)
    http.read_timeout = options[:timeout]
    response = http.request_head("/avatar/#{hash}?rating=#  {options[:rating]}&default=http://gravatar.com/avatar")
    response.code != '302'
  rescue StandardError, Timeout::Error
    true
  end

end

My problem is that since the gravatar is shown in the upper right corner of every page in my application, the gravatar?(user) is run on every request which is very expensive and time-consuming.

Is there a way to run the function only once, say on sign in, and cache its return value? I tried to store the return value in an instance variable, but couldn't get it to work properly.

Thanks for any advice.

Was it helpful?

Solution

Store the flag in the session once you figure out if the user has a gravatar or not after user logs-in. But, please make sure to clear it off when the user logs out.

OTHER TIPS

You can store it in user object itself (and persist in the database). This way, the next time user logs in, you won't have to do gravatar resolution.

Now you have another (more difficult) problem: when to invalidate this cache?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top