Question

I'm using the omniauth-twitter gem to authenticate users and to fill in names, avatars, etc. with this in my User.rb file

  def self.from_omniauth(auth)
    where(auth.slice("provider", "uid")).first || create_from_omniauth(auth)
  end

  def self.create_from_omniauth(auth)
    create! do |user|
      user.provider = auth["provider"]
      user.uid = auth["uid"]
      user.name = auth["info"]["name"]
      user.nickname = auth["info"]["nickname"]
      user.location = auth["info"]["location"]
      user.image = auth["info"]["image"].sub("_normal", "")
      user.description = auth["info"]["description"]
    end
  end
end

Works great, except I happened to change my avatar in Twitter and noticed that the data never changes even after I log out and reauthorize. It would be nice if data like location, image, description got refreshed each time a user logged in.

Was it helpful?

Solution

Well, the workings of that logic are up to you. Here's an example of a possible solution:

def self.from_omniauth(auth)
  user = find_by(auth.slice(:provider, :uid)) || initialize_from_omniauth(auth) # Rails 4
  user = where(auth.slice(:provider, :uid)).first || initialize_from_omniauth(auth) # Rails 3
  user.update_dynamic_attributes(auth)
end

def self.initialize_from_omniauth(auth)
  new do |user|
    user.provider = auth[:provider]
    user.uid = auth[:uid]
    user.name = auth[:info][:name]
  end
end

def update_dynamic_attributes(auth)
  self.location = auth[:info][:location]
  self.image = auth[:info][:image]
  self.description = auth[:info][:description]
  save!
  self
end

Also, you don't have to do this:

auth["info"]["image"].sub("_normal", "")

As the omniauth-twitter gem can already do that for you if you use the image_size option:

OmniAuth::Builder do
  provider :twitter, ENV["TWITTER_KEY"], ENV["TWITTER_SECRET"], {
    :image_size => 'original'
  }
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top