I use the gem 'omniauth-twitter' to let my user login to my app. Then I can use their name and profile image from twitter on my app.
The problem I am facing is that when a user update its name or image on twitter, it doesn't update on my app.
Here is my config:
app/controllers/omniauth_callbacks_controller.rb
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def all
user = User.from_omniauth(request.env["omniauth.auth"])
if user.persisted?
flash.notice = "Signed in!"
sign_in_and_redirect user
else
session["devise.user_attributes"] = user.attributes
redirect_to new_user_registration_url
end
end
alias_method :twitter, :all
end
app/models/user.rb
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.nickname
user.image = auth["info"]["image"].sub("_normal", "")
end
end
def self.new_with_session(params, session)
if session["devise.user_attributes"]
new(session["devise.user_attributes"]) do |user|
user.attributes = params
user.valid?
end
else
super
end
end
end
I did not suceed to update user attributes. Any ideas following my configuration to do this ? thanks.
I believe you may be mistaken about the semantics of #first_or_create
. The correct semantics is:
A) try finding a record with the provided query scope (your where clause -> provider: auth.provider, uid: auth.uid
)
B.1) If found any, return the first one not executing the passed in block.
B.2) If not found any, initialize a new one and pass it to the block passed as argument (which in your case is what sets the name and image)
So, on the first login, the program flow follows A > B.2, which creates a new user with the correct name and image. On the successive logins, it follows A > B.1, which just return the user already on the database.
You can solve this issue ensuring the code that sets name and picture always runs:
def self.from_omniauth(auth)
user = find_or_initialize_by(provider: auth.provider, uid: auth.uid)
user.name = auth.info.nickname
user.image = auth["info"]["image"].sub("_normal", "")
user.save
user
end
Cheers!