Reputation: 1494
I am building the Facebook Oauth by using the facebook-omniauth
gem. I wrote this method to create the user based on the auth data.
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.email = auth.info.email
user.password = Devise.friendly_token[0, 20]
user.username = check_username(auth.info.email)
user.remote_avatar_url = get_image_url(auth)
user.skip_confirmation!
end
end
and for username
generation I wrote this method where it check that the given username is currently present or not.
def self.check_username(value)
username = value.split("@").first
byebug
while(User.where(username: username).exists?)
username += rand(100).to_s
end
username
end
There is very strange error is happening or may be I am not aware of something. Here when I try to execute User.where(username: username)
which should be results into the
select * from users where username=username
it is actually executing
User.where(username: username)
CACHE (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`provider` = 'google_oauth2' AND `users`.`uid` = '101977206788010441641' AND `users`.`username` = 'ashjambhulkar'
even when I try to simply fetch all the users record it gives
(byebug) User.all
CACHE (0.0ms) SELECT `users`.* FROM `users` WHERE `users`.`provider` = 'google_oauth2' AND `users`.`uid` = '101977206788010441641' [["provider", "google_oauth2"], ["uid", "101977241641"]]
#<ActiveRecord::Relation []>
how can i modify this query that it will get executed normally.
Upvotes: 0
Views: 199
Reputation: 29308
The issue is that you are calling that method inside the first_or_create
block.
first_or_create
is literally that first || create(*args, &block)
. Now when create
is called with a block all queries inside that block are scoped to the current scope via a method called scoping
Docs State: "Scope all queries to the current scope. ... Please check unscoped if you want to remove all previous scopes (including the default_scope) during the execution of a block.
With an example of:
Comment.where(post_id: 1).scoping do
Comment.first
end
=> SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = 1 ORDER BY "comments"."id" ASC LIMIT 1
You should be able to resolve this via
def self.check_username(value)
username = value.split("@").first
while(User.unscoped.where(username: username).exists?)
username += rand(100).to_s
end
username
end
Upvotes: 2