2

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.

1 Answer 1

2

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
Sign up to request clarification or add additional context in comments.

6 Comments

Finally got around to trying this and data is still not updating. It's very strange because the approach looks solid.
I forgot that you have to use self inside of the instance method, otherwise it just creates a local variable.
Tried that. Doesn't work. Even when I clear the image, description, and/or location fields in the console (and clear all caches, restart server, etc.) it never gets changed when I re-authorize with Twitter. I delete the user entirely and get the latest profile... but that's really desirable. :) Very weird.
I tried the code this time and it definitely works. Check out this sample application.
I more closely followed the pattern the Sessions controller in the sample you provided, and it worked. Looks like I was skipping everything if I found an existing user in my Sessions controller. Thanks a million for the example!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.