Reputation: 8734
I have some code to find a user for Oauth using Omniauth.
If the user signs in with say Facebook on day 1, changes their email address with FB on day 2 and signs back into my app on day 3 I want to update the email address on file.
The code below should sync email address. I use AwesomePrint to write the email address to the console and they are different. However save returns true but the email address does not update?
def self.find_or_create_for_oauth(auth)
social_identity = SocialIdentity.find_for_oauth(auth.provider, auth.uid)
email = auth.info.email
if social_identity.nil?
user = find_by_email(email)
if user.nil?
# create user for email with random password
end
social_identity = user.social_identities.create!(
provider: auth.provider,
uid: auth.uid
)
end
user = social_identity.user
ap user.email # email address 1
ap email # email address 2
if user.email != email
user.email = email
ap user.save! # returns true
end
user # still has email address 1
end
I removed all console writes except for these two:
if user.email != email
user.email = email
puts user.email
user.save!
puts user.email
end
My console returns these (fake) email addresses: [email protected] & [email protected]. Save is resetting the email address instead of saving it.
So I decided to rather just post the entire method below in case their is something strange going on:
class User
has_many :social_identities, dependent: :destroy
def self.find_or_create_for_oauth(auth)
social_identity = SocialIdentity.find_for_oauth(auth.provider, auth.uid)
email = auth.info.email
if social_identity.nil?
user = find_by_email(email)
if user.nil?
random_password = generate_password
user = User.new(
email: email,
password: random_password,
password_confirmation: random_password)
user.skip_confirmation!
user.save!
end
social_identity = user.social_identities.create!(
provider: auth.provider,
uid: auth.uid
)
end
user = social_identity.user
if user.email != email
user.email = email
puts user.email
user.save!
puts user.email
end
user
end
end
class SocialIdentity < ActiveRecord::Base
belongs_to :user
validates :user_id, presence: true
validates :provider, presence: true
validates :uid, presence: true,
uniqueness: { scope: [:provider, :deleted_at] }
acts_as_paranoid
def self.find_for_oauth(provider, uid)
where(provider: provider, uid: uid).first
end
end
Upvotes: 6
Views: 2704
Reputation: 5095
Are you checking the db state after the method being performed or just relying on these puts?
Sometimes it is good to write puts user.reload.email
Anyways, I would analyze the logs to see if there isn't any validation or a callback being triggered which rollbacks the changes or adheres the process in any other way. Also, I would try to do user.update_column('email', email)
to see if that works. update_column
skips any validations or callbacks.
Upvotes: 4