问题
I have an app with user authentication with devise + omniauth.
In my model that username in my app is unique. I dont want duplicate username in my app.
Some users in facebook has not a defined username in his profile.
I want generate an unique username if the user has not username defined in facebook.
For example for generate password I have this:
:password => Devise.friendly_token[0,20]
How can I generate a unique username for my app if the facebook user has not username in facebook?
Thank you
回答1:
You can take a part of email before the @ sign and add there smth like user_id, or just take the email itself. Or you can combine somehow the first and last names from the fb response.
回答2:
You can create a nice readable username (eg generated from the first part of the email) and then ensure it is unique by adding numbers until it is. eg
#in User
def get_unique_login
login_part = self.email.split("@").first
new_login = login_part.dup
num = 2
while(User.find_by_login(new_login).count > 0)
new_login = "#{login_part}#{num}"
num += 1
end
new_login
end
One problem here is that someone could potentially bag that login inbetween you getting it and you saving it. So, maybe it's best to combine it into a before_create filter:
#in User
before_create :ensure_login_uniqueness
def ensure_login_uniqueness
if self.login.blank? || User.find_by_login(self.login).count > 0
login_part = self.email.split("@").first
new_login = login_part.dup
num = 2
while(User.find_by_login(new_login).count > 0)
new_login = "#{login_part}#{num}"
num += 1
end
self.login = new_login
end
end
回答3:
Here is how i created Login with combination of first name and last name field.. Improvements on this code is welcome.
before_create :ensure_login_uniqueness
def ensure_login_uniqueness
if self.login.blank?
self.name = self.first_name + " " + self.last_name
firstnamePart = self.first_name.downcase.strip.gsub(' ', '').gsub(/[^\w-]/, '')
lastnamePart = self.last_name.downcase.strip.gsub(' ', '').gsub(/[^\w-]/, '')
login_part = firstnamePart+lastnamePart
new_login = login_part.dup
num = 1
while(User.where(:login => new_login).count > 0)
new_login = "#{login_part}#{num}"
num += 1
end
self.login = new_login
end
end
回答4:
It did not work for me,but change:
while(User.find_by_login(new_login).count > 0)
to
while(User.where(login: new_login).count > 0)
回答5:
Here's my methods that I use for Facebook
def ensure_username_uniqueness
self.username ||= self.email.split("@").first
num = 2
until(User.find_by(username: self.username).nil?)
self.username = "#{username_part}#{num}"
num += 1
end
end
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 = auth.info.name.downcase.gsub(" ", "")
user.username = user.username[0..29] if user.username.length > 30
user.ensure_username_uniqueness
end
end
来源:https://stackoverflow.com/questions/9905418/generate-unique-username-omniauth-devise