Search code examples
ruby-on-railsrubynullgravatar

How to use Helper to show Gravatars with Feed?


On the activities feed we are attempting to list out the gravatar images, but keep running into an error message.

index.html.erb

<% @activities.each do |activity| %>
    <%= gravatar_for @user, size: 50 %>
<% end %>

module UsersHelper

# Returns the Gravatar for the given user.
def gravatar_for(user, options = { size: 80 })

    if user.email.nil? #creates error
    gravatar_id = Digest::MD5::hexdigest((0...8).map { (65 + rand(26)).chr }.join+"@mailinator.com")
    else
    gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
    end

  size = options[:size]
  gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}?s=#{size}"
  image_tag(gravatar_url, alt: user.name, class: "gravatar")
end
end

NoMethodError in Activities#index

undefined method `email' for nil:NilClass
Line: if user.email.nil?

If we remove .email, then error shows for .name. If we remove that too then error messages go away, but then only a default gravatar image shows instead of the user's custom image.

gravatar images show correctly when views are generated directly from the users_controller. There is the model relationship of user's has_many :activities and activities belongs_to :user.

class ActivitiesController < ApplicationController
    def index
        @activities = Activity.order("created_at desc").where(current_user.following_ids)
    end
end

I greatly appreciate your time & expertise!


Solution

  • It seems like you want to be able to call this method even if there is no user logged in (aka user is nil). You can get around this problem, by defining an anonymous user. The most simple version could look like this:

    def gravatar_for(user, options = { size: 80 })
    
      unless user
        identifier = Array.new(8) { ('a'..'z').to_a.sample }.join
        user = User.new(name: 'Anonymous', email: "#{identifier}@mailinator.com")
      end
    
      gravatar_id  = Digest::MD5::hexdigest(user.email.downcase)
      gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}?s=#{options[:size]}"
      image_tag(gravatar_url, alt: user.name, class: "gravatar")
    end