Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails save returns true but doesn't save anything

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

Further update:

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
like image 490
Lee Avatar asked May 29 '14 10:05

Lee


1 Answers

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.

like image 150
socjopata Avatar answered Oct 19 '22 22:10

socjopata