我有一个带有devise + omniauth用户身份验证的应用。
在我的模型中,我的应用中的用户名是唯一。我不想在我的应用中使用重复的用户名。
Facebook中的某些用户在其个人资料中没有定义的用户名。
如果用户没有在facebook中定义用户名,我想生成一个唯一的用户名。
例如,对于生成密码,我有这个:
:password => Devise.friendly_token[0,20]
如果Facebook用户在Facebook中没有用户名,我怎样才能为我的应用生成唯一的用户名?
谢谢
答案 0 :(得分:11)
您可以创建一个很好的可读用户名(例如从电子邮件的第一部分生成),然后通过添加数字来确保它是唯一的。例如
#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
这里的一个问题是,有人可能会在你获得它并保存它之间将登录包装起来。所以,也许最好把它组合成一个before_create过滤器:
#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
答案 1 :(得分:2)
你可以在@符号之前接收电子邮件的一部分,并像user_id一样添加smth,或者只是接收电子邮件本身。或者你可以以某种方式结合fb响应中的名字和姓氏。
答案 2 :(得分:2)
以下是我使用名字和姓氏字段组合创建登录的方法。欢迎使用此代码的改进。
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
答案 3 :(得分:1)
它对我不起作用,但改变了:
while(User.find_by_login(new_login).count > 0)
到
while(User.where(login: new_login).count > 0)
答案 4 :(得分:1)
这是我用于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
答案 5 :(得分:0)
这是从“全名”生成“用户名”的方法
def self.generate_username(full_name)
generated = ActiveSupport::Inflector.transliterate(full_name) # change ñ => n
.downcase # only lower case
.strip # remove spaces around the string
.gsub(/[^a-z]/, '_') # any character that is not a letter or a number will be _
.gsub(/\A_+/, '') # remove underscores at the beginning
.gsub(/_+\Z/, '') # remove underscores at the end
.gsub(/_+/, '_')
taken_usernames = User
.where("username LIKE ?", "#{generated}%")
.pluck(:username)
# username if it's free
return generated unless taken_usernames.include?(generated)
count = 2
while true
# username_2, username_3...
new_username = "#{generated}_#{count}"
return new_username if ! taken_usernames.include?(new_username)
count += 1
end
end